2012-07-16 51 views
4

我有一个我得到的场景Class name as a string我只是想创建该类的通用List。我试过以下使用反射的通用列表

  Type _type = Type.GetType(className); 

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

但是iam geting error。我无法将这个_type作为列表参数。如果有人知道请帮我

+2

你为什么要那样做?我敢打赌你1000美元,你试图做的事情是愚蠢的,会导致糟糕的设计。 – Euphoric 2012-07-16 17:51:49

+0

我会扔进另一个盛大。 – 2012-07-16 17:54:19

+0

这似乎是一种潜在的不良模式。你能提供一些关于这个打算解决的问题的更多细节吗?为什么你的班级名字通过一个字符串?这是某种自定义序列化器的一部分吗? – JamieSee 2012-07-16 17:57:27

回答

10

最近你可以得到:

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

如果_type类在另一个类库中,可能吗? – Nithesh 2012-07-17 05:33:26

+0

只要'_type'正在引用它。 – 2012-07-17 06:10:48

0

不幸的是,这是不可能的,因为泛型需要在编译时知道。您正尝试通过在运行时使它们为已知来重新定义它。他们需要在编译时知道的原因是编译器可以验证传递给它的所有变量都是有效的。 AFAIK,做你想做的事情需要彻底重写泛型。

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

什么@MarkusJarderot说是最接近你可以使用接口而不是泛型。

2

反射发生在运行时,因为对象的类型可以通过正在运行的程序更改为任何东西。

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

因此,使用反射指定类型参数是不可能的,因为编译器将不知道任何关于反射结果的信息。

1

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

例如,使用dynamic可以让您调用列表,你可以不通过投做IListAddRanges方法:

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}); 

但是,这种方法并不像几乎一样类型 - 因为它在编译时无法捕获错误,因此可以安全地转换为非通用接口。