Generic list by using reflection

2019-01-19 06:38发布

问题:

I have a scenario on which i got Class name as a string I just want to create a generic List of that class. I tried the following

            Type _type = Type.GetType(className);

            List<_type> list = new List<_type>();

But iam geting error. I can't gave that _type as list argument. If anybody knows please help me

回答1:

Closest you can get:

Type listType = typeof(List<>).MakeGenericType(_type);
IList list = (IList) Activator.CreateInstance(listType);


回答2:

Reflection takes place during runtime, as the type of an object could be changed to anything by a running program.

Type parameters (generics), on the other hand, are only used by the compiler, to check type safety.

So it's not possible to use reflection specify a type parameter, because the compiler will not know anything about the result of reflection.



回答3:

If you are using .Net 4, then using dynamic may help. In this case you will be able to use methods on the instance that are not accessible through non-generic interfaces (such as IList).

For example, using dynamic allows you to invoke the AddRanges method of the list, which you couldn't do through a cast to IList:

Type _type = typeof(int);
Type listType = typeof(List<>).MakeGenericType(_type); 
dynamic list = Activator.CreateInstance(listType); 

list.Add(1);   
list.AddRange(new int[] {0, 1, 2, 3});  

However, this method is not as nearly as type-safe as casting to a non-generic interface, because it cannot catch errors at compile time.



回答4:

Unfortunately, this is not possible as generics need to be known at compile time. You are trying to redefine this by making them known at runtime. The reason they need to be known at compile time is so the compiler can verify that all variables passed to it are valid. AFAIK, doing what you want to go would require a complete rewrite of generics.

The main reason behind compile time checking is that _type can change at runtime and then there would be overhead in adding to the List<T> as the JIT compiler would need to do type checking.

What @MarkusJarderot said is the closest you can get as interfaces are used instead of generics.