简体   繁体   English

C#泛型如何影响具有基元的集合

[英]How does C# generics affect collections with primitives

As I understand it, C#/.Net generics support some degree of reification. 据我了解,C#/ .Net泛型支持某种程度的具体化。 So, if I have the following code: 所以,如果我有以下代码:

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

Will the value 1 be autoboxed or will the 'list' object handle primitive ints efficiently? 值1是自动装箱还是'list'对象会有效地处理原始int?

No, it won't be boxed. 不,它不会被装箱。 At execution time, the backing array for the List<int> will genuinely be an int[] . 在执行时, List<int>的后备数组将真正是一个int[] Note that this isn't just the case with genuine primitive types - List<T> won't box values of any value type (assuming it's been declared as List<Guid> etc rather than List<object> ). 请注意,这不仅仅是真正原始类型的情况 - List<T>不会对任何值类型的框值(假设它已被声明为List<Guid> etc而不是List<object> )。

Basically, generics in .NET keep a lot more of their information than they do in Java - the CLR natively understands generics and deals with them appropriately, rather than in Java where the JVM is pretty much ignorant of them. 基本上,.NET中的泛型比Java中更多地保留了他们的信息--CLR本身理解泛型并适当地处理它们,而不是在Java中,JVM几乎不了解它们。

For example, if you write: 例如,如果你写:

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

Then type will be equal to typeof(List<string>) - which is then different to (say) List<Guid> etc. 然后type将等于typeof(List<string>) - 然后它与(例如) List<Guid>等不同。

The int values will not be boxed within the list. int值不会在列表中装箱。 This is one of the beauties with generics, that the compiler (more specifically the JIT-compiler, I believe) will construct a typed version of the List<> class, rather than storing the values as object . 这是泛型的美女之一,编译器(更确切地说是JIT编译器,我相信)将构造List<>类的类型化版本 ,而不是将值存储为object So it does not only enforce type safety through the exposed methods and properties, but it is genuinely typed in all aspects. 因此,它不仅通过暴露的方法和属性强制实施类型安全,而且它在所有方面都是真正的类型。

As others have noted, the jitter generates new code for every construction involving a new value type. 正如其他人所指出的那样,抖动会为涉及新值类型的每个构造生成新代码。 An interesting point not yet mentioned so far is that the jitter will generate code once for a reference type construction and re-use that for every reference type. 到目前为止尚未提及的一个有趣的观点是,抖动将为参考类型构造生成一次代码,并为每种引用类型重新使用该代码。 The code for List<object> is exactly the same as the code for List<string> . List<object>的代码与List<string>的代码完全相同。

That might sound crazy, but remember, generics are not templates. 这可能听起来很疯狂,但请记住,泛型不是模板。 By the time the code for the generic method body IL is emitted, overload resolution and other relevant semantic analysis is already done by the C# compiler. 当发出泛型方法体IL的代码时,C#编译器已经完成了重载解析和其他相关的语义分析。

.NET generics are getting specialized for structs, thus there is no boxing required in your case. .NET泛型正在专门针对结构,因此在您的情况下不需要装箱。 Note that there is no need for casting too anyway. 请注意,无论如何都不需要进行铸造。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM