箱和拆箱这​​是什么意思?拆箱这

2023-09-03 16:11:32 作者:深海情劫

可能显示的文件:   为什么我们需要装箱和拆箱在C#?   What是装箱和拆箱,什么是权衡?

Possible Duplicates: Why do we need boxing and unboxing in C#? What is boxing and unboxing and what are the trade offs?

在C#什么母鹿坐的手段:框和拆箱

In C# what doe sit means: "Box and UnBox"?

下面从MSDN,我创办了文本的摘录。

Here an extract from MSDN where I founded the Text.

不过,这种便利是有代价的。   任何引用或值类型是   添加到一个ArrayList是隐式   上溯造型到对象。如果项是   值类型,它们必须被装箱时,   它们被添加到列表中,并且   装箱时,他们被检索。都   铸造和拳击和   拆箱操作降低   性能;拳击的效果和   开箱可以在非常显著   情况下,您必须遍历   大集合。

But this convenience comes at a cost. Any reference or value type that is added to an ArrayList is implicitly upcast to Object. If the items are value types, they must be boxed when they are added to the list, and unboxed when they are retrieved. Both the casting and the boxing and unboxing operations decrease performance; the effect of boxing and unboxing can be very significant in scenarios where you must iterate over large collections.

谢谢!

推荐答案

下面是一个更详细的解释,即着眼于内部公共语言运行库。

Here is a more detailed explanation that looks at the internal of Common Language Runtime.

首先,让我们的值类型和引用类型的区别:

First, let's make the difference between value types and reference types:

的值类型是举行的堆栈和它的一个副本传递给调用的方法 的参考值是在托管堆举行,堆栈只保存一个指针(引用)它的位置。的位置,而不是对象,被传递给调用的方法 A value type is held on the stack and a copy of it is passed to called methods A reference value is held in the managed heap and the stack holds only a pointer (reference) to its location. The location, and not the object, is passed to called methods

如果您不知道堆栈是什么(不要生气),那就是拥有一个方法的局部变量和用于返回指令(仅仅是短暂的,并提供了一​​个通用的答案)。当你调用一个方法,在堆栈上有足够面积的静态分配给它,所以堆栈分配总是被调用静态分配。

If you don't know what the stack is (don't be offended), it's a memory area that holds local variables in a method and addresses of caller functions used for return instruction (just to be brief and provide a general answer). When you call a method, a sufficient area on the stack is statically allocated to it, so stack allocation is always called static allocation.

堆,取而代之的,是从堆栈,的属性的运行过程中,其中分配必须首先要求操作系统分开的存储区域,这就是为什么它被称为动态分配(如果你没有在运行,如果语句,例如,内存可能不会被分配给您的进程,而不是堆栈总是被分配)。

The heap, instead, is a memory area separated from the stack, property of the running process, in which allocation must be first demanded to the operating system, and that's why it's called dynamic allocation (if you don't run in an if statement, for example, memory may not be allocated for your process, instead stack is always allocated).

只是为了让最后一个例子,在堆和栈:在语言如C ++,声明 INT [100]一; 静态分配100 * 8个字节的堆栈( 64位系统的假设),而 INT * A =新的INT [100]; 声明了一个8个字节(64位系统)领域的堆栈,并要求800以上字节堆上,如果和(如有)。

Just to make a final example on heap and stack: in languages such as C++, declaring int[100] a; statically allocates 100*8 bytes on the stack (64-bit system assumed), while int* a = new int[100]; declares a 8 bytes (on 64-bit systems) area on the stack AND requests 800 more bytes on the heap, if and where available.

现在让我们来谈谈C#:

Now let's talk about C#:

由于int是值类型,并且被分配在栈上,当你将它转换为对象或其他任何引用类型(居然还有从INT可以继承任何其他的引用类型,但它是一个一般的规则)的值必然成为引用类型。所以在堆上一个新区域被分配,则该对象的盒装的里面和栈保存指向它的指针。

Since int is a value type, and is allocated on the stack, when you cast it to object or any other reference type (actually there is no other reference type from which int can inherit, but it's a general rule) the value must become necessarily a reference type. So a new area on the heap is allocated, the object is boxed inside it and the stack holds a pointer to it.

正好相反:当你有一个引用类型,如对象,并希望将其转换为一个值类型,如int,则新的值必须保持在堆栈上,所以CLR去堆, UN-箱的值,并将其复制到堆栈中。

Just the opposite: when you have a reference type, such as object, and want to cast it to a value type, such as to int, the new value must be held on the stack, so CLR goes to heap, un-boxes the value and copies it to the stack.

记住 INT [] INT * 的例子吗?简单地说,当你有 INT 在C#中,运行时预计其堆栈单元为保存值而是当你有对象,它预计其真正的价值是在指向的堆栈中的堆的位置。

Remember the int[] and int* examples? Simply, when you have int in C#, the runtime expects its stack location to hold the value but instead when you have object, it expects its real value to be in the heap location pointed by the stack.

相关推荐