【问题标题】:Generic list by using reflection使用反射的通用列表
【发布时间】:2012-07-16 17:47:00
【问题描述】:

我有一个场景,我得到了Class name as a string 我只想创建该类的通用List。我尝试了以下

            Type _type = Type.GetType(className);

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

但是我得到了error。我不能将该 _type 作为列表参数。如果有人知道请帮帮我

【问题讨论】:

  • 你为什么要这样做?我和你打赌 1000 美元,你正在尝试做的事情是愚蠢的,会导致糟糕的设计。
  • 这似乎是一个潜在的错误模式。您能否提供更多有关这要解决的问题的详细信息?为什么您的班级名称以字符串形式出现?这是某种自定义序列化程序的一部分吗?
  • 但我只是想概括一下场景......实际上我需要从 DataAccess 本身返回通用列表。也想概括一下方法..
  • 那你就不需要泛型了,但是你可以使用非泛型的List。
  • @Euphoric 如果你不介意请解释一下吗?

标签: c# reflection generic-list


【解决方案1】:

你能得到的最接近的:

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

【讨论】:

  • 如果_type类在另一个类库中是否可以?
  • 只要_type 引用它。
【解决方案2】:

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

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

所以不能使用反射指定类型参数,因为编译器不会知道反射的结果。

【讨论】:

    【解决方案3】:

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

    例如,使用dynamic 允许您调用列表的AddRanges 方法,而这无法通过转换为IList 来实现:

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

    但是,此方法不像强制转换为非泛型接口那样类型安全,因为它无法在编译时捕获错误。

    【讨论】:

      【解决方案4】:

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

      编译时检查背后的主要原因是 _type 可以在运行时更改,然后添加到 List&lt;T&gt; 会产生开销,因为 JIT 编译器需要进行类型检查。

      @MarkusJarderot 所说的是你可以得到的最接近的,因为使用的是接口而不是泛型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-19
        • 1970-01-01
        • 2013-05-24
        • 1970-01-01
        相关资源
        最近更新 更多