This really has my stumped today. I’m sure its simple, but… Here is my sample code:
using System; using System.Collections; namespace ConsoleApplication1 { class Program { public ArrayList SomeProp { get; set; } static void Main(string[] args) { // Get the Type of a property by reflection. Type myPropType = typeof(Program).GetProperty('SomeProp').PropertyType; // Create an instance of the determined Type. var x = Activator.CreateInstance(myPropType); // Now try to use that instance, passing to a method that takes a generic. WhatAmI(x); Console.ReadKey(); } private static void WhatAmI<T>(T x) { Console.WriteLine('T is: ' + typeof(T).FullName); Console.WriteLine('x is: ' + x.GetType().FullName); } } }
The output here is:
T is: System.Object x is: System.Collections.ArrayList
Basically what is going on here is I have some property on some class. It doesnt really matter what/where that comes from. The important part is that I get the PropertyInfo for that property. From there I create a new instance of its Type with Activator.
Now If I pass that created instance to a function that takes a generic parameter, the generic Type always comes across as Object, because Activator.CreateInstance() returns an Object, so ‘var x’ is an Object, not, in this case, an ArrayList.
What I need to happen is for the generic type to be the actual type, int his case ‘ArrayList’.
I know there is an Activator.CreateInstance() that I can use instead, but I can’t use a Type (PropertyInfo.PropertyType) within the angle brackets for that method.
I could also just cast the returned object, like:
myPropType x = (myPropType)Activator.CreateInstance(myPropType);
But obviously that doesn’t compile… Plus it wouldn’t be valid anyway because the cast is compile time, and I don’t know the type until runtime, but conceptually its what I need…
So I’m stuck with this Type, but I can’t figure out how to get it passed over to the WhatAmI() method, and have T be ArrayList, not Object.
Ideas?
To call generic methods using a
Typeat runtime, you need to use reflection – andMakeGenericMethodin particular, something like:Otherwise, the compiler infers the
<T>from the variable type –objectin this case.One side point here is that you can improve things by only doing the reflection once – i.e. don’t use
Activator, but use a generic constraint instead:Defines the method without an arg, but with a default constructor; then:
calls the method just using the type – the instance is created inside the method. This is usually faster than repeated reflection.