1

Is it possible to mix generics with Type arguments? For example, is there a way to write code like this:

IList GetListOfListsOfTypes(Type[] types)
{
    IList<IList> listOfLists = new List<IList>();

    foreach (Type t in types)
    {
        listOfLists.Add(new List<t>());
    }

    return listOfLists.ToList();
}

Clearly, the compiler does not like this, but is there some way to achieve this?

MrCodeMnky
  • 835
  • 1
  • 6
  • 18
  • 2
    You can't get it to work with the compiler. But you can call the generic constructor using reflection. – driis Oct 16 '13 at 20:54
  • possible duplicate of http://stackoverflow.com/questions/1603170/conversion-of-system-array-to-list – Marvin Smit Oct 16 '13 at 20:55
  • 2
    This is not a duplicate of that because it uses generic types whereas the link only specifies static system types. – Travis J Oct 16 '13 at 21:03

1 Answers1

4

To do it with reflection, you must construct the closed generic type from the open type; then construct it with one of the options we have for that with reflection. Activator.CreateInstance works well for that:

IList GetListOfListsOfTypes(Type[] types)
{
    IList<IList> listOfLists = new List<IList>();

    foreach (Type t in types)
    {
        Type requestedTypeDefinition = typeof(List<>);
        Type genericType = requestedTypeDefinition.MakeGenericType(t);
        IList newList = (IList)Activator.CreateInstance(genericType);
        listOfLists.Add(newList);
    }

    return listOfLists;
}

Just be aware that you are returning a list of non-generic ILists from this method, which is necessary since we don't know the types at compile time, so in order to use your new generic lists, you probably need to use reflection again. Consider if it's worth it - of course, it depends on your requirements.

driis
  • 161,458
  • 45
  • 265
  • 341
  • +1 - This is nice because it will actually retain the proper type for the children Lists after the parent List is returned. – Travis J Oct 16 '13 at 21:01