C# Add()方法内部

C# Add()方法内部,c#,list,add,internals,C#,List,Add,Internals,大多数C#开发人员都知道,System.Collections.Generic包含List类。该类公开Add方法,其实现如下: [__DynamicallyInvokable] public void Add(T item) { if (this._size == this._items.Length) { this.EnsureCapacity(this._size + 1); } T[] arg_36_0 = this._items;

大多数C#开发人员都知道,System.Collections.Generic包含List类。该类公开Add方法,其实现如下:

[__DynamicallyInvokable]
public void Add(T item)
{
    if (this._size == this._items.Length)
    {
        this.EnsureCapacity(this._size + 1);
    }
    T[] arg_36_0 = this._items;
    int size = this._size;
    this._size = size + 1;
    arg_36_0[size] = item;
    this._version++;
}
我正在努力了解这是如何工作的。。。 我有一个类型为T的局部数组,称为“\u items”,还有“\u size”和“\u version”变量。添加新项时,将创建一个类型为T的新数组,称为“arg_36_0”,专用数组将分配给新数组。复制大小;然后增加本地大小,并将传递的新项分配给新创建的数组。
因此,此函数完成后,本地“arg_36_0”数组将被删除,该项永远不会分配给实际数组(称为“_项”)。我在这里遗漏了什么?:)

您缺少引用类型语义

T[] arg_36_0 = this._items
将只创建对完全相同数组的新引用

引用类型的要点是,你对其中一个引用所做的任何事情都会反映在所有引用上

因此
arg_36_0[大小]=项目将更改基础数组。你也可以这样写:

int size = this._size;
this._size = size + 1;
this._items[size] = item; // set the last element in the array
this._version++;
想象一下,你会有这样一门课:

class MyClass
{
    int MyProperty { get; set; }
}
并创建它的一个实例:

var a = new MyClass();
如果现在向该对象引入第二个引用,您将看到
a
b
上的更改:

var b = a;
b.MyProperty = 3; // this changes the underlying object and thus is reflected in a also
Console.WriteLine(a.MyProperty); // prints 3

不是移除数组,而是移除对它的引用。您只有一个数组,而不是两个。你在其中一个引用上所做的任何事情都会通过另一个引用反映出来。要认识到的重要一点是数组是引用类型而不是值类型,因此
arg\u 36\u 0
是一个变量,它引用与
\u item
相同的数组,当你向数组中添加值时,实际上是在向同一数组中添加值
\u item
引用的数组。这行代码在做什么?arg_36_0[大小]=项目@jdweng它正在索引
大小
处添加新的
,这是新的(增加的)大小。但不要与数组的容量混用。@srh当您查看实际代码时,您会发现它只使用了一个引用。上面的代码只是反编译代码,不必为可读性进行优化。