使用反射的通用列表

时间:2012-07-16 17:47:01

标签: c# reflection generic-list

我有一个我得到Class name as a string的场景我只想创建该类的通用List。我尝试了以下

            Type _type = Type.GetType(className);

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

但是我正在寻找error。我不能把那个_type作为列表参数。如果有人知道请帮帮我

4 个答案:

答案 0 :(得分:11)

最近,你可以得到:

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

答案 1 :(得分:2)

反射发生在运行时,因为正在运行的程序可以将对象的类型更改为任何内容。

另一方面,类型参数(泛型)仅供编译器使用,以检查类型安全性。

所以不可能使用反射指定一个类型参数,因为编译器不会知道有关反射结果的任何信息。

答案 2 :(得分:1)

如果您使用的是.Net 4,那么使用dynamic可能有所帮助。在这种情况下,您将能够在实例上使用无法通过非通用接口访问的方法(例如IList)。

例如,使用dynamic可以调用列表的AddRanges方法,而这种方法无法通过强制转换为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});  

但是,这种方法并不像转换为非泛型接口那样类型安全,因为它无法在编译时捕获错误。

答案 3 :(得分:0)

不幸的是,这是不可能的,因为在编译时需要知道泛型。您正试图通过在运行时将它们公开来重新定义它。它们需要在编译时知道的原因是编译器可以验证传递给它的所有变量是否有效。 AFAIK,做你想做的事情需要完全重写泛型。

编译时检查的主要原因是_type可以在运行时更改,然后在添加List<T>时会有开销,因为JIT编译器需要进行类型检查。

@MarkusJarderot所说的是最接近你使用的接口而不是泛型。