【问题标题】:How does C# generics affect collections with primitivesC# 泛型如何影响具有基元的集合
【发布时间】:2011-04-14 01:41:33
【问题描述】:

据我了解,C#/.Net 泛型支持某种程度的具体化。所以,如果我有以下代码:

List<int> list = new List<int>();
list.Add(1);

值 1 会被自动装箱还是“列表”对象会有效地处理原始整数?

【问题讨论】:

    标签: c# .net generics reification


    【解决方案1】:

    不,它不会被装箱。在执行时,List&lt;int&gt; 的后备数组将真正是int[]。请注意,这不仅适用于真正的原始类型 - List&lt;T&gt; 不会装箱 any 值类型的值(假设它被声明为 List&lt;Guid&gt; 等而不是 List&lt;object&gt;)。

    基本上,.NET 中的泛型比在 Java 中保留更多的信息 - CLR 本身就可以理解泛型并适当地处理它们,而不是在 Java 中,JVM 几乎不知道它们。

    例如,如果你写:

    object list = new List<string>();
    Type type = list.GetType();
    

    然后type 将等于typeof(List&lt;string&gt;) - 然后不同于(例如)List&lt;Guid&gt; 等。

    【讨论】:

      【解决方案2】:

      int 值不会在列表中加框。这是泛型的优点之一,编译器(更具体地说是 JIT 编译器,我相信)将构造List&lt;&gt; 类的类型化版本,而不是将值存储为@987654323 @。因此,它不仅通过公开的方法和属性来强制执行类型安全,而且在所有方面都是真正的类型化。

      【讨论】:

        【解决方案3】:

        正如其他人所指出的,抖动会为每个涉及新值类型的构造生成新代码。到目前为止还没有提到的一个有趣的点是,抖动将为引用类型构造生成代码一次,并为每个引用类型重复使用该代码。 List&lt;object&gt; 的代码与List&lt;string&gt; 的代码完全相同。

        这听起来可能很疯狂,但请记住,泛型不是模板。在发出泛型方法体 IL 的代码时,C# 编译器已经完成重载解析和其他相关语义分析。

        【讨论】:

        • 但是,对 new T[10] 的调用仍然会创建正确的数组类型,即使对于引用类型也是如此。
        【解决方案4】:

        .NET 泛型正在专门用于结构,因此在您的情况下不需要装箱。请注意,无论如何也不需要强制转换。

        【讨论】:

          猜你喜欢
          • 2016-06-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-05
          • 1970-01-01
          • 2012-08-05
          • 1970-01-01
          相关资源
          最近更新 更多