数组与泛型列表——存储值类型——它是如何存储的,访问期间内存中会发生什么

本文关键字:存储 访问期间 内存 什么 何存储 列表 泛型 类型 数组 | 更新日期: 2023-09-27 18:01:00

这是一个简单的问题,但我想了解在这个问题中内存中发生了什么。

我理解将值类型转换为引用类型是装箱。

int I = 10;
object obj = I; // boxing - I is moved from stack to heap

1.int数组的情况:

int[] arrInt = new int[1];
arrInt[0] = 10;
int I = arrInt[0];

在这里,我知道arrInt在堆栈中(带有到堆的地址(,并且会指向存储"10"的堆。

在这种情况下,10是否"装箱"并存储在堆中?还是作为未装箱的值类型存在?那么,当我访问回项目时,int I = arrInt[0]会发生什么?

2.如果是int泛型列表:

List<int> lstInt = new List<int>(){10};
int I = lstInt[0];

在通用List<int>的情况下,在msdn文档中,它引用using generic collections avoids the overhead of boxing:"http://msdn.microsoft.com/en-us/library/vstudio/ms172194(v=vs.100(.aspx"但我不明白,在泛型中List的情况下,整数值是如何存储的?这是否意味着,它以未装箱的形式存在?那么,在这种情况下,如果我访问int I = lstInt[0],在这种情形下会发生什么?

谢谢。

数组与泛型列表——存储值类型——它是如何存储的,访问期间内存中会发生什么

在这种情况下,10是否"装箱"并存储在堆中?还是作为未装箱的值类型存在?

由于您定义了类型为int[]的数组,因此该值未装箱。

那么,当我访问该项时,int I=arrInt[0]会发生什么?

在这种情况下,该值直接从数组内的内存位置读取。没有开箱。只是一个32位值的简单副本。

但我不明白,在泛型中List的情况下,整数值是如何存储的?

在后台,List<T>在内部将值存储在T[]数组中。所以那里没有拳击比赛。如果反编译List<T>类,您会看到它的Items属性(索引器(看起来像这样:

public T this[int index]
{
    get
    {
        if (index >= this._size) ThrowHelper.ThrowArgumentOutOfRangeException();
        return this._items[index];
    }
    set
    {
        if (index >= this._size) ThrowHelper.ThrowArgumentOutOfRangeException();
        this._items[index] = value;
        this._version++;
    }
}

这里,_items实例字段定义如下:

private T[] _items;

使用通用集合可以避免装箱的开销

ArrayList等非通用版本相比,它避免了装箱的开销。ArrayList在后台使用object[]数组,这会导致值类型被装箱。

List<>在封面下使用一个数组,因此在这两种情况下发生的情况是相同的。

当您将一个int放入一个数组时,它不会被装箱,只是被复制。

int i = 10;
int j = i;    // copy contents of 'i' to 'j'
a[0] = i;     // copy contents of 'i' to 'a[0]'

数组在堆上分配,当ij是正常的局部变量时,它们在堆栈上。但这些都被视为"实施细节"。

 myObject.X = i;  // copy contents of 'i' to 'X' 

CCD_ 17和CCD_。