【发布时间】:2011-04-14 01:41:33
【问题描述】:
据我了解,C#/.Net 泛型支持某种程度的具体化。所以,如果我有以下代码:
List<int> list = new List<int>();
list.Add(1);
值 1 会被自动装箱还是“列表”对象会有效地处理原始整数?
【问题讨论】:
标签: c# .net generics reification
据我了解,C#/.Net 泛型支持某种程度的具体化。所以,如果我有以下代码:
List<int> list = new List<int>();
list.Add(1);
值 1 会被自动装箱还是“列表”对象会有效地处理原始整数?
【问题讨论】:
标签: c# .net generics reification
不,它不会被装箱。在执行时,List<int> 的后备数组将真正是int[]。请注意,这不仅适用于真正的原始类型 - List<T> 不会装箱 any 值类型的值(假设它被声明为 List<Guid> 等而不是 List<object>)。
基本上,.NET 中的泛型比在 Java 中保留更多的信息 - CLR 本身就可以理解泛型并适当地处理它们,而不是在 Java 中,JVM 几乎不知道它们。
例如,如果你写:
object list = new List<string>();
Type type = list.GetType();
然后type 将等于typeof(List<string>) - 然后不同于(例如)List<Guid> 等。
【讨论】:
int 值不会在列表中加框。这是泛型的优点之一,编译器(更具体地说是 JIT 编译器,我相信)将构造List<> 类的类型化版本,而不是将值存储为@987654323 @。因此,它不仅通过公开的方法和属性来强制执行类型安全,而且在所有方面都是真正的类型化。
【讨论】:
正如其他人所指出的,抖动会为每个涉及新值类型的构造生成新代码。到目前为止还没有提到的一个有趣的点是,抖动将为引用类型构造生成代码一次,并为每个引用类型重复使用该代码。 List<object> 的代码与List<string> 的代码完全相同。
这听起来可能很疯狂,但请记住,泛型不是模板。在发出泛型方法体 IL 的代码时,C# 编译器已经完成重载解析和其他相关语义分析。
【讨论】:
new T[10] 的调用仍然会创建正确的数组类型,即使对于引用类型也是如此。
.NET 泛型正在专门用于结构,因此在您的情况下不需要装箱。请注意,无论如何也不需要强制转换。
【讨论】: