如何使用反射创建的列表作为正常创建列表

时间:2013-08-06 18:53:54

标签: c# list generics reflection

我使用此帖子中的方法创建了一个列表 Create list of variable type

Assembly assembly = Assembly.Load("ConsoleApplication4");
Type mytype = assembly.GetType("ConsoleApplication4.TestClass");
Type genericList = typeof(List<>).MakeGenericType(mytype);  
var mylist = Activator.CreateInstance(genericList);

我的问题是,在创建列表后,如何在以下函数中使用该列表:

public void TestFunction<T>(List<T> mylist)
{
//do something here
}

3 个答案:

答案 0 :(得分:1)

您将失去静态类型分析和编译时检查(然后再次,鉴于您正在使用已经发生的反射),因此您可以重新编写TestFunction作为:

public void TestFunction(dynamic myList)
{
  // do something here
}

答案 1 :(得分:1)

您只需更改实例化列表的最后一行

即可
dynamic mylist = Activator.CreateInstance(genericList);

这样编译器不会尝试推断myList的(运行时)类型,但会将此任务推迟到DLR,在您的情况下,DLR很乐意告诉您它是List<mytype>

如果您在某个时候知道mylist的具体类型,您当然也可以使用简单的演员

TestFunction((List<knownType>)mylist);

哪一个更喜欢主要是品味问题,两者之间可能存在性能差异,但与基于反射的实例化相比,差异可能不会成为瓶颈,但如果性能是主要关注点,则使用分析器。

我建议在实例化站点而不是在方法签名中使用dynamic的原因是为了使大多数代码静态类型化,以便编译器可以检查大部分代码。通过在方法签名中使用dynamic,您将对该方法的所有调用进行动态调用,而如果您动态键入mylist,则只使用mylist将语句转换为动态调用。

答案 2 :(得分:0)

您无法以您希望的方式使用mylist实例,因为编译器无法推断List的封闭类型。您只能使用其他反射方法或使用开放的泛型类型进行检查。