据我了解,C#/.Net 泛型支持某种程度的具体化。所以,如果我有以下代码:
List<int> list = new List<int>();
list.Add(1);
值 1 会被自动装箱还是“列表”对象会有效地处理原始整数?
据我了解,C#/.Net 泛型支持某种程度的具体化。所以,如果我有以下代码:
List<int> list = new List<int>();
list.Add(1);
值 1 会被自动装箱还是“列表”对象会有效地处理原始整数?
不,它不会被装箱。在执行时, 的支持数组List<int>
将真正是一个int[]
. 请注意,这不仅适用于真正的原始类型 -List<T>
不会将任何值类型的值装箱(假设它被声明为List<Guid>
etc 而不是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<>
而不是将值存储为object
. 因此,它不仅通过公开的方法和属性来强制执行类型安全,而且在所有方面都是真正的类型化。
正如其他人所指出的,抖动会为每个涉及新值类型的构造生成新代码。到目前为止还没有提到的一个有趣的点是,抖动将为引用类型构造生成一次代码,然后为每个引用类型重复使用该代码。的代码List<object>
与 的代码完全相同List<string>
。
这听起来可能很疯狂,但请记住,泛型不是模板。当泛型方法体 IL 的代码发出时,C# 编译器已经完成了重载解析和其他相关语义分析。
.NET 泛型正在专门用于结构,因此在您的情况下不需要装箱。请注意,无论如何也不需要强制转换。