tags:

views:

3633

answers:

3

The title is kind of obscure. What I want to know is if this is possible:

string typeName = <read type name from somwhere>;
Type myType = Type.GetType(typeName);

MyGenericClass<myType> myGenericClass = new MyGenericClass<myType>();

Obviously, MyGenericClass is described as:

public class MyGenericClass<T>

Right now, the compiler complains that 'The type or namespace 'myType' could not be found." There has got to be a way to do this.

+9  A: 

Unfortunately no there is not. Generic arguments must be resolvable at Compile time as either 1) a valid type or 2) another generic parameter. There is no way to create generic instances based on runtime values without the big hammer of using reflection.

JaredPar
+17  A: 

You can't do this without reflection. However, you can do it with reflection. Here's a complete example:

using System;
using System.Reflection;

public class Generic<T>
{
    public Generic()
    {
        Console.WriteLine("T={0}", typeof(T));
    }
}

class Test
{
    static void Main()
    {
        string typeName = "System.String";
        Type typeArgument = Type.GetType(typeName);

        Type genericClass = typeof(Generic<>);
        // MakeGenericType is badly named
        Type constructedClass = genericClass.MakeGenericType(typeArgument);

        object created = Activator.CreateInstance(constructedClass);
    }
}
Jon Skeet
OK, this is good, but how does one go about calling methods on created? More reflection?
Robert C. Barth
Well, if you can get away with making your generic type implement a non-generic interface, you can cast to that interface. Alternatively, you could write your own generic method which does all of the work you want to do with the generic, and call *that* with reflection.
Jon Skeet
(You then wouldn't have to call MakeGenericType etc, because constructing the instance of the generic type would be done inside the generic method too.)
Jon Skeet
Yeah, I dont undertand how to use created if the only info you have about the type returned is in the typeArgument type variable? It seems to me like you would have to cast to that variable, but you dont know what it is so Im not sure if you can do that with reflection. Another question if the object is for example of type int if you pass it as an object variable into say fro example a List<int> wil this work? will the variable created be treated as an int?
theringostarrs
@jimioh: Yes, if you call a method with reflection and it takes a value type parameter, the argument will be unboxed on the way in. You're right that you'd need to cast the created object elsewhere, but often that's okay.
Jon Skeet
+1  A: 

*Alternatively, you could write your own generic method which does all of the work you want to do with the generic, and call that with reflection.*

Can you please give an example of this solution?