【问题标题】:C# instantiate generic List from reflected Type [duplicate]C#从反射类型实例化通用列表[重复]
【发布时间】:2011-01-11 18:28:45
【问题描述】:

是否可以从 C# (.Net 2.0) 中的反射类型创建通用对象?

void foobar(Type t){
    IList<t> newList = new List<t>(); //this doesn't work
    //...
}

类型 t 直到运行时才知道。

【问题讨论】:

  • 您希望如何处理在编译时不知道其类型的列表?
  • 你能把它写成一个通用函数吗,如void foobar&lt;T&gt;() { IList&lt;T&gt; newList = new List&lt;T&gt;(); }
  • 我感觉这可能是代码异味,因为以糟糕的方式处理更大的问题。
  • 我发布了一个关于手头更大问题的单独问题:stackoverflow.com/questions/4661734/…

标签: c# reflection generics


【解决方案1】:

试试这个:

void foobar(Type t)
{
    var listType = typeof(List<>);
    var constructedListType = listType.MakeGenericType(t);

    var instance = Activator.CreateInstance(constructedListType);
}

现在如何处理instance?由于您不知道列表内容的类型,因此您可以做的最好的事情可能是将instance 转换为IList,这样您就可以拥有除object 之外的其他内容:

// Now you have a list - it isn't strongly typed but at least you
// can work with it and use it to some degree.
var instance = (IList)Activator.CreateInstance(constructedListType);

【讨论】:

  • +1 for typeof(List&lt;&gt;),我以前没见过这个。
  • var 是否存在于 .Net framework 2.0 中?!
  • @sprocketonline: var 是 C# 3 的功能,因此如果您使用 C# 2,则需要显式声明变量。
  • 谢谢,这个答案对我帮助很大。正是我需要的(我正在为 EF 构建表达式)
【解决方案2】:
static void Main(string[] args)
{
  IList list = foobar(typeof(string));
  list.Add("foo");
  list.Add("bar");
  foreach (string s in list)
    Console.WriteLine(s);
  Console.ReadKey();
}

private static IList foobar(Type t)
{
  var listType = typeof(List<>);
  var constructedListType = listType.MakeGenericType(t);
  var instance = Activator.CreateInstance(constructedListType);
  return (IList)instance;
}

【讨论】:

  • +1 记住旧的非泛型支持的接口 :)
  • 同样的技巧适用于IDictionary :)
【解决方案3】:

您可以使用MakeGenericType 进行此类操作。

有关文档,请参阅 herehere

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多