什么是数组索引?

Art*_*tro 4 c# arrays indexing

我知道List<T>索引器就像属性一样.取自msdn:

索引器允许类或结构的实例 数组一样被索引.索引器类似于属性,除了它们的访问器接受参数.

但我不明白为什么会发生以下情况:

int[] myArray = new int[0];
List<int> myList = new List<int>();

Interlocked.Increment(ref myArray[0]);  // fine

Interlocked.Increment(ref myList[0]);   //CS0206    A property or indexer may not be passed as an out or ref parameter
Run Code Online (Sandbox Code Playgroud)

他们不应该以同样的方式工作吗?

Zei*_*kki 7

索引器List<T>允许您使用属性(方法)访问元素,使其看起来像一个数组.您无法通过ref所写的方式传递生成的方法:

Interlocked.Increment(ref myList.GetItem.get_Item(0));
Run Code Online (Sandbox Code Playgroud)

但访问数组的元素不是索引器.CLR直接支持访问数组元素.因此array[i]返回一个可以传递的变量ref.

来自C#规格:

即使访问索引器元素的语法与数组元素的语法相同,索引器元素也不会被归类为变量.因此,不可能将索引器元素作为ref或out参数传递.

这是List<T>(内部使用数组)的索引器:

public T this[int index]
{
    get
    { // some checks removed 
        return _items[index];
    }

    set { _items[index] = value;}
}
Run Code Online (Sandbox Code Playgroud)

来自IL Side:

访问数组元素会生成此直接IL指令:

IL_0014: ldelem.i4

通过索引器访问List的元素会生成:

IL_001b:  callvirt   instance !0 class [mscorlib]System.Collections.Generic.List`1<int32>::get_Item(int32)
Run Code Online (Sandbox Code Playgroud)

所以,它是相同的c#语法.但生成的IL完全不同.