如何在.NET对象堆中存储值类型数组?

在.NET中,诸如int之类的值类型对象存储在内存中。

引用类型对象需要为引用和对象单独分配内存,并且对象存储在.NET对象堆中。

并且在堆中创建了数组,那么如何在堆中存储诸如int []之类的值类型数组? 是否意味着值类型对象可以存储在堆中而不需要装箱?

是的,你是对的。 我建议你读这个:

http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx

它非常好,几乎可以解释你想知道的一切。

是的,数组是一种可以在没有装箱的情况下将值类型值存储在堆上的方法。 另一种是将它放在正常的课程中:

public class Foo { int value1; string name; // etc } 

Foo实例关联的所有变量都存储在堆上。 value1的值只是int ,而name的值是字符串引用。

这就是为什么“值类型存储在堆栈中,引用类型存储在堆上”的说法显然是不正确的。

但是,正如Eric Lippert 正确地指出的那样 ,堆栈/堆的区别是一个实现细节。 例如,CLR的未来版本可以在堆栈上存储一些对象,如果它可以解决方法终止后不需要它们。

是的,这意味着没有为到达元素进行装箱,因为整个数组作为一个整体被“装箱”在一个Array对象内(虽然这不是它所谓的)。

实际上并没有要求在放入堆之前必须将值类型装箱。 您可以通过三种方式在堆上放置值类型:

  1. 通过将其包装在常规对象中。

  2. 通过拳击它。

  3. 通过将其包装在数组对象中。

可能有更多的方法,但我认为我没有错过任何方式。)

用这种方式想一想,内存中的对象位置是由它的类型和声明的位置来定义的。 如果对象是值类型,则其存储在您声明变量的位置。 如果对象是引用类型,则其引用将存储在您声明变量的位置,而实际对象实例存在于堆上。

声明局部变量时,您将声明堆栈上的变量。 因此,值类型的值将在堆栈上。 引用类型的引用将在堆栈上,并且对象实例仍在堆上。

如果在类(引用类型)中声明实例变量,则实际上是在堆中声明实例变量。 值类型的值将在堆中(在对象实例中)。 引用类型的引用也将在堆中(在对象实例中),对象实例将在堆中的其他位置。

如果在结构(值类型)中声明实例变量,它所在的位置取决于声明底层结构的位置。

对于int int[]数组,数组是引用类型,您可以将对该类型声明为“fields”的int值视为整数,因此您的整数有效地存在于堆中。