0

How can I get this to work? var x = error type or namespace name expected.

class Program
{
    static void Main(string[] args)
    {
        Person j = new John();
        var t = j.GetType();
        var x = new List<t>();
    }
}

class John : Person
{

}

class Person
{
    public string Name;
}
4
  • 4
    Because generics aren't dynamic. They're a compile-time .NET type feature, not a runtime feature.
    – BoltClock
    Commented Sep 10, 2011 at 12:43
  • 1
    If you REALLY want, you can do it using reflection, but it's a pain to create the List and to use the list (unless you cast it to one of the non-generic interfaces it has, like IEnumerable).
    – xanatos
    Commented Sep 10, 2011 at 12:45
  • @xantos - not really that hard to create and use. See my answer. Commented Sep 10, 2011 at 12:56
  • @Preet You beat me of 1m30 you know, I was writing nearly the same piece of code. And you forgot an a in my name :-)
    – xanatos
    Commented Sep 10, 2011 at 14:20

3 Answers 3

3

It is not possible to use generics like that. All type parameters of generic classes and functions have to be known at compile time (i.e. they have to be hardcoded), while in your case the result of j.GetType() can only be known at run time.

Generics are designed to provide compile-type safety, so this restriction cannot be lifted. It can be worked around in some cases, e.g. you can call a generic method with a type parameter that is only known at compile time using Reflection, but this is generally something you should avoid if possible.

3

You can do it, but you have to use reflection to do so.

    static void Main(string[] args)
    {
        Person j = new John();
        var t = j.GetType();
        Type genType = Type.MakeGenericType(new Type[] { typeof(List<>) });
        IList x =  (IList) Activator.CreateInstance(genType, t);        
    }

or really simply:

    static void Main(string[] args)
    {
        Type genType = Type.MakeGenericType(new Type[] { typeof(List<>) });
        IList x =  (IList) Activator.CreateInstance(genType, typeof(John)); 
    }

You'll have to use the IList Interface as you need to add stuff to the list

3
  • The problem with this is that once you cross the border of Reflection-land, there's no going back. You can't use the type you constructed with static code.
    – Jon
    Commented Sep 10, 2011 at 12:50
  • @jon - what do you mean? you can cast that object to a List<John> as that's what it is. Commented Sep 10, 2011 at 14:21
  • If you cast it to List<Person> you need to hardcode the cast (including the type) -- so what benefit did you get from reflecting? As xanatos says, in this specific case you can cast to IList and get some functionality, but you are still stuck with object instead of Person instances. In the general case, the object is totally unusable by code except if you continue with reflection.
    – Jon
    Commented Sep 10, 2011 at 14:30
2

Because generics must be known at compile time. In List<T>, T must be a constant type, for example List<Person>.

Not the answer you're looking for? Browse other questions tagged or ask your own question.