I have that code:
myDataGrid is an object passed to the method. I know it is type of OvserveableCollection of different types.
All I need is to cast that object to OvserveableCollection<T> (it implements the IEnumerable interface)
//get element's type
Type entryType = (myDataGrid as IEnumerable).AsQueryable().ElementType;
foreach (var item in (IEnumerable<entryType>)myDataGrid)
{}
but the compiler doesn't know the entryType in the loop header. Why ?
You can't use a runtime Type instance as a generic type parameter unless you use reflection (MakeGenericMethod() / MakeGenericType()). However I doubt it would help anyway! In this scenario, either use the non-generic IEnumerable (no <T>) API, or perhaps cast to a known interface/subclass, or use dynamic as a last resort duck-typing.
You can also use MakeGenericMethod() etc, but that is more involved and almost certainly slower.
For example:
foreach(object item in (IEnumerable)myDataGrid)
{
// tada!
}
Another trick can be to use dynamic to invoke the generic code:
public void Iterate<T>(IEnumerable<T> data)
{
foreach(T item in data) {...}
}
...
dynamic evil = myDataGrid;
Iterate(evil);
You're trying to use a Type variable as a type argument for a generic type. Generics don't work that way - you have to use a compile-time type as the type argument. (That compile-time type can be a type parameter itself, if you're doing this in a generic method.)
It's hard to know how to advise you to change the code without knowing more about your requirements though - what do you need to do with the items?
You can't cast to a "runtime type"... in order to "write" the instructions which actually implement that cast, the compiler requires the Type... which really just means that the Type must be known at COMPILE time.
The ONLY way I've ever found around this limitation was code-generator (of one sort or another) to "manually" generate the IL instructions to perform the cast. It's hard to know what to recommend unless we know a lot about your actual requirements (and constraints).
Cheers. Keith.
Related
I am doing some reflection stuff. I have the following situation:
I have a variable Type myType with some runtime value (e.g. string or List<int>).
I have two variables object a and object b for which I know that they are of type IImmutableSet<myType>. (So if myType=string they'd be IImmutableSet<string>, if myType=List<int> they'd be IImmutableSet<List<int>> and so on.)
How can I cast them?
Motivation:
I want to do a comparison of a and b by content, i,e.
check that both their size is equal. For that, I need a Count property (or equivalent property/method).
check that a contains all elements of b. For that, I need a Contains(...) method.
If I had ISet<T>s, I'd just cast them to ICollection and use that interface's Count and Contains(...).
But since IImmutableSet<T> does not implement any non-generic collection interface, I need to cast a and b to IImmutableSet<myType> (or IReadOnlyCollection<myType>). That syntax doesn't work because it expects a compile-time constant type.
--
Another thought... if casting isn't possible, I'd be happy with being able to call the said methods. Since I'm already doing heavy reflection, I don't care about speed.
This question gives me curiosity... When you want to define a type you must say GetType(Type) ex.: GetType(string), but ain't String a type itself?
Why do you need to use GetType in those situations? And, if the reason is because it is expecting a Type 'Type'... why isn't the conversion implicit... I mean, all the data is there...
What you're doing is getting a reference to the meta-data of the type ... it might be a little more obvious if you look at the C# version of the API, which is typeof(string) ... which returns a Type object with information about the string type.
You would generally do this when using reflection or other meta-programming techniques
string is type, int is type and Type is type and they are not the same. but about why there is no implicit conversion it's not recommended by MSDN:
By eliminating unnecessary casts,
implicit conversions can improve
source code readability. However,
because implicit conversions can occur
without the programmer's specifying
them, care must be taken to prevent
unpleasant surprises. In general,
implicit conversion operators should
never throw exceptions and never lose
information so that they can be used
safely without the programmer's
awareness. If a conversion operator
cannot meet those criteria, it should
be marked explicit.
Take attention to :
never lose information so that they
can be used safely without the
programmer's awareness
When you want to define a type you must say GetType(Type) ex.: GetType(string)...
That's not true. Every time you do any of the following
class MyClass
{
///...
}
class MyChildClass : MyClass
{
}
struct MyStruct
{
///...
}
you're defining a new type.
if the reason is because it is expecting a Type 'Type'... why isn't the conversion implicit... I mean, all the data is there...
One reason for this is polymorphism. For instance, if we were allowed to do the following:
MyChildClass x;
....GetType(x)
GetType(x) could return MyChildClass, MyClass, or Object, since x is really an instance of all of those types.
It's also worth noting that Type is itself a class (ie, it inherits from Object), so you can inherit from it. Although I'm not sure why you'd want to do this other than overriding the default reflection behavior (for instance, to hide the internals from prying eyes).
GetType(string) will return the same information. Look at it like you would a constant. The only other way to get the Type object that represents a string would be to instantiate the string object and call o.GetType(). Also, this is not possible for interfaces and abstract types.
If you want to know the runtime type of a variable, call the .GetType() method off of it, as the runtime type may not be the same as the declared type of the variable.
I get an IEnumerable which I know is a object array. I also know the datatype of the elements. Now I need to cast this to an IEnumerable<T>, where T is a supplied type. For instance
IEnumerable results = GetUsers();
Type t = GetType(); //Say this returns User
IEnumerable<T> users = ConvertToTypedIEnumerable(results, t);
I now want to cast/ convert this to IEnumerable<User>. Also, I want to be able to do this for any type.
I cannot use IEnumerable.Cast<>, because for that I have to know the type to cast it to at compile time, which I don't have. I get the type and the IEnumerable at runtime.
-
Thanks
You can use reflection to call Cast<> with a runtime type. See this answer: How to call a generic method through reflection
However, at some point you'll still have to know the type of the item at compile time if you ever want to manipulate it as such without reflection. Just having an IEnumerable<T> instance cast as an object/IEnumerable still won't really do you any more good than just having the IEnumerable by itself. It's likely that you need to rethink what you're doing.
Is there ever a reason to use Type parameters over generics, ie:
// this...
void Foo(Type T);
// ...over this.
void Foo<T>();
It seems to me that generics are far more useful in that they provide generic constraints and with C# 4.0, contravarience and covarience, as well as probably some other features I don't know about. It would seem to me that the generic form has all the pluses, and no negatives that the first doesn't also share. So, are there any cases where you'd use the first instead?
Absolutely: when you don't know the type until execution time. For example:
foreach (Type t in someAssembly.GetTypes())
{
Foo(t);
}
Doing that when Foo is generic is painful. It's doable but painful.
It also allows the parameter to be null, which can be helpful in some situations.
Well they really aren't the same at all.
With the second one, you've actually got a class of the compile-time type there (whatever has been passed in by whoever). So you can call specific functions on it (say if it's all of some given interface).
In your first example, you've got an object of class 'Type'. So you'll need to still determine what it is and do a cast to do anything useful with it.
Foo(someVariable.GetType()); // allowed
Foo<someVariable.GetType()>(); // illegal
I'm very excited about the dynamic features in C# (C#4 dynamic keyword - why not?), especially because in certain Library parts of my code I use a lot of reflection.
My question is twofold:
1. does "dynamic" replace Generics, as in the case below?
Generics method:
public static void Do_Something_If_Object_Not_Null<SomeType>(SomeType ObjToTest) {
//test object is not null, regardless of its Type
if (!EqualityComparer<SomeType>.Default.Equals(ObjToTest, default(SomeType))) {
//do something
}
}
dynamic method(??):
public static void Do_Something_If_Object_Not_Null(dynamic ObjToTest) {
//test object is not null, regardless of its Type?? but how?
if (ObjToTest != null) {
//do something
}
}
2. does "dynamic" now allow for methods to return Anonymous types, as in the case below?:
public static List<dynamic> ReturnAnonymousType() {
return MyDataContext.SomeEntities.Entity.Select(e => e.Property1, e.Property2).ToList();
}
cool, cheers
EDIT:
Having thought through my question a little more, and in light of the answers, I see I completely messed up the main generic/dynamic question. They are indeed completely different. So yeah, thanks for all the info.
What about point 2 though?
dynamic might simplify a limited number of reflection scenarios (where you know the member-name up front, but there is no interface) - in particular, it might help with generic operators (although other answers exist) - but other than the generic operators trick, there is little crossover with generics.
Generics allow you to know (at compile time) about the type you are working with - conversely, dynamic doesn't care about the type.
In particular - generics allow you to specify and prove a number of conditions about a type - i.e. it might implement some interface, or have a public parameterless constructor. dynamic doesn't help with either: it doesn't support interfaces, and worse than simply not caring about interfaces, it means that we can't even see explicit interface implementations with dynamic.
Additionally, dynamic is really a special case of object, so boxing comes into play, but with a vengence.
In reality, you should limit your use of dynamic to a few cases:
COM interop
DLR interop
maybe some light duck typing
maybe some generic operators
For all other cases, generics and regular C# are the way to go.
To answer your question. No.
Generics gives you "algorithm reuse" - you write code independent of a data Type. the dynamic keyword doesn't do anything related to this. I define List<T> and then i can use it for List of strings, ints, etc...
Type safety: The whole compile time checking debate. Dynamic variables will not alert you with compile time warnings/errors in case you make a mistake they will just blow up at runtime if the method you attempt to invoke is missing. Static vs Dynamic typing debate
Performance : Generics improves the performance for algorithms/code using Value types by a significant order of magnitude. It prevents the whole boxing-unboxing cycle that cost us pre-Generics. Dynamic doesn't do anything for this too.
What the dynamic keyword would give you is
simpler code (when you are interoperating with Excel lets say..) You don't need to specify the name of the classes or the object model. If you invoke the right methods, the runtime will take care of invoking that method if it exists in the object at that time. The compiler lets you get away even if the method is not defined. However it implies that this will be slower than making a compiler-verified/static-typed method call since the CLR would have to perform checks before making a dynamic var field/method invoke.
The dynamic variable can hold different types of objects at different points of time - You're not bound to a specific family or type of objects.
To answer your first question, generics are resolved compile time, dynamic types at runtime. So there is a definite difference in type safety and speed.
Dynamic classes and Generics are completely different concepts. With generics you define types at compile time. They don't change, they are not dynamic. You just put a "placeholder" to some class or method to make the calling code define the type.
Dynamic methods are defined at runtime. You don't have compile-time type safety there. The dynamic class is similar as if you have object references and call methods by its string names using reflection.
Answer to the second question: You can return anonymous types in C# 3.0. Cast the type to object, return it and use reflection to access it's members. The dynamic keyword is just syntactic sugar for that.