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

xpo*_*ort 9 c#

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

怎么做?

Dar*_*rov 23

Type x = typeof(Foo);
Type listType = typeof(List<>).MakeGenericType(x);
object list = Activator.CreateInstance(listType);
Run Code Online (Sandbox Code Playgroud)

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

  • 如果在运行时创建类型,请确保不存在任何编译时类型安全性. (2认同)

Fra*_*ank 11

你当然可以:

var fooList = Activator
    .CreateInstance(typeof(List<>)
    .MakeGenericType(Foo.GetType()));
Run Code Online (Sandbox Code Playgroud)

这里的问题是fooList类型,object所以你仍然必须将它转换为"可用"类型.但是这种类型会是什么样的?由于支持添加和查找类型T List<T>(或更确切IList<>)对象的数据结构不协变,T因此您无法将其List<Foo>转换为List<IFoo>where Foo: IFoo.你可以把它投射到一个IEnumerable<T>协变的T.

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

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