如何实例化List <t>但T在运行时才知道?</t>

时间:2010-10-08 07:08:00

标签: c#

假设我有一个在运行时才知道的类。 在运行时,我得到一个引用类型为x的引用,引用到Foo.GetType()。 只有使用x和List&lt;&gt;,才能创建Foo类型的列表吗?

怎么做?

4 个答案:

答案 0 :(得分:22)

Type x = typeof(Foo);
Type listType = typeof(List<>).MakeGenericType(x);
object list = Activator.CreateInstance(listType);

当然,您不应期望任何类型安全,因为结果列表在编译时的类型为object。使用List<object>会更实用但仍然限制类型安全性,因为Foo的类型仅在运行时才知道。

答案 1 :(得分:11)

当然可以:

var fooList = Activator
    .CreateInstance(typeof(List<>)
    .MakeGenericType(Foo.GetType()));

这里的问题是fooList的类型为object,因此您仍然需要将其转换为“可用”类型。但是这种类型会是什么样的?由于支持添加和查找T List<T>类型对象(或更确切地说IList<>)的数据结构在T中不协变,因此您无法转换List<Foo>List<IFoo> Foo: IFoo。您可以将其转换为IEnumerable<T>中的协变变量T

如果您使用的是C#4.0,您还可以考虑将fooList转换为dynamic,这样您至少可以将其用作列表(例如添加,查找和删除对象)。

考虑到所有这些以及事实,即使在运行时创建类型时你没有任何编译时类型安全性,在这种情况下简单地使用List<object>可能是最好/最实用的方法

答案 2 :(得分:0)

这样的事情:

Activator.CreateInstance(typeof运算(列表与LT;&GT;)MakeGenericType(类型))

答案 3 :(得分:-1)

给定一个类型,你可以用这种方式实例化一个新实例:

var obj = Activator.CreateInstance(type);

参考:http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx