与泛型拳击和拆箱 [英] Boxing and unboxing with generics

查看:134
本文介绍了与泛型拳击和拆箱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(例如)创建集合的.NET 1.0方法是:

  ArrayList list = new ArrayList() ; 
list.Add(i); / *拳击* /
int j =(int)list [0]; / *拆箱* /

使用这个的惩罚是由于拳击造成的类型安全和性能的缺失并且取消装箱。

.NET 2.0的方式是使用泛型:

 列表与LT; INT> list = new List< int>(); 
list.Add(i);
int j = list [0];

拳击的价格(以我的理解)是需要在堆上创建一个对象,copy堆栈将整数分配给新对象,反之亦然,以便拆箱。



泛型的使用如何克服这个问题?堆栈分配的整数是否停留在堆栈上并从堆中指向(我猜这不是这种情况,因为当它超出范围时会发生什么)?好像还有需要将它复制到其他地方。



真正发生了什么?

T [] 数组来避免装箱/取消装箱。 List< T> 例如使用一个 T [] 数组来存储它的内容。 b

数组当然是一个引用类型,因此(在当前版本的CLR中,yada yada)存储在堆中。但由于它是 T [] 而不是 object [] ,所以数组的元素可以直接存储:也就是说,它们仍然在堆上,但是它们在数组中的堆 上,而不是被装箱并使数组包含对这些框的引用。



因此,对于 List< int> ,例如,你在数组中会看起来像这样:

 
[1 2 3]

code> ArrayList ,它使用一个对象[] ,因此会看起来像这样:

 
[* a * b * c]

...其中 * a 等是对象的引用(盒装整数):

 
* a - > 1
* b - > 2
* c - > 3

原谅那些简单的插图;希望你知道我的意思。


The .NET 1.0 way of creating collection of integers (for example) was:

ArrayList list = new ArrayList();
list.Add(i);          /* boxing   */
int j = (int)list[0]; /* unboxing */

The penalty of using this is the lack of type safety and performance due to boxing and unboxing.

The .NET 2.0 way is to use generics:

List<int> list = new List<int>();
list.Add(i);
int j = list[0];

The price of boxing (to my understanding) is the need to create an object on the heap, copy the stack allocated integer to the new object and vice-versa for unboxing.

How does the use of generics overcome this? Does the stack-allocated integer stays on the stack and being pointed to from the heap (I guess this is not the case because of what will happen when it will get out of scope)? It seems like there is still a need of copying it somewhere else out of the stack.

What is really going on?

解决方案

When it comes to collections, generics make it possible to avoid boxing/unboxing by utilizing actual T[] arrays internally. List<T> for example uses a T[] array to store its contents.

The array, of course, is a reference type and is therefore (in the current version of the CLR, yada yada) stored on the heap. But since it's a T[] and not an object[], the array's elements can be stored "directly": that is, they're still on the heap, but they're on the heap in the array instead of being boxed and having the array contain references to the boxes.

So for a List<int>, for example, what you'd have in the array would "look" like this:

[ 1 2 3 ]

Compare this to an ArrayList, which uses an object[] and would therefore "look" something like this:

[ *a *b *c ]

...where *a, etc. are references to objects (boxed integers):

*a -> 1
*b -> 2
*c -> 3

Excuse those crude illustrations; hopefully you know what I mean.

这篇关于与泛型拳击和拆箱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆