tags:

views:

163

answers:

4

Hi all,

Is it possible to create a new List<T> where the T is dynamically set at runtime?

Cheers

+6  A: 

Yes. You can do this via Reflection, using Type.MakeGenericType and Activator.CreateInstance.

IList MakeListOfType(Type listType)
{
    Type listType = typeof(List<>);
    Type specificListType = listType.MakeGenericType(listType);

    return (IList)Activator.CreateInstance(specificListType);
}
Reed Copsey
Why the downvotes?
Reed Copsey
you have a parameter listType and a local field listType, I imagine some people would be confused by that (I didn't downvote)
Martin
A: 

yes using generic you can do something like this

    var asd = METHOD<Button>();

    List<t> METHOD<t>()
    {
        return new List<t>();
    }
Luiscencio
why? =(........
Luiscencio
the type "Button" is hardcoded, that's not runtime
Martin
@Luiscencio the OP asked for the t to be determined at runtime. In your example, its set at compile time.
John Buchanan
shame on me... a
Luiscencio
+10  A: 

It's possible, but not necessarily useful, since you couldn't actually use it from compiled code as strongly typed. The creation code would be

    Type myType;
    Type listType = typeof(List<>).MakeGenericType(myType);
    IList myList = (IList)Activator.CreateInstance(listType);
Dan Bryant
Works. Cheers! :)
AndyC
Please note there is a difference between 'strongly-typed' and 'statically-typed'. You lose static type checking here but myList will prevent you from adding objects which are not valid myType instances.
Lee
@Lee, thanks for the clarification.
Dan Bryant
A: 

Yes. However, you won't be able to assign it to a variable that has a generic type since the T in this case will not be decided until runtime. (If you are thinking that the .NET 4.0 covariance feature will help you and let you declare the variable as IList<SomeSuperType>, it won't as the T is used by List<T> for both in and out purposes.)

Note the unusual List<> syntax in order to access the "unconstructed" generic type.

    public static System.Collections.IList ConstructGenericList(Type t)
    {
        return (System.Collections.IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(t));
    }
binarycoder
(re variance; that also only works for interfaces / delegates; not classes)
Marc Gravell
@Marc, right... I should have wrote `IList<SomeSuperType>`. Fixing.
binarycoder