数组索引器签名返回对象 - 它是否为空?

bri*_*ght 5 .net c# arrays indexer list

我无意中发现的事实是,索引器this[int index] { get; }的工作方式不同的结构数组比它的结构的列表.也就是说,索引器在T[]返回对数组内元素的引用的情况下,而索引器在List<T>返回元素的副本的情况下.

这是一个非常大的语义和性能差异,我很高兴能够T[]让我们解决性能限制List<T>.

但是,我对实际实施感到困惑.的代码Array由此在.NET参考源如下:

Object IList.this[int index] {
    get { return GetValue(index); }
    set { SetValue(value, index); }
}
Run Code Online (Sandbox Code Playgroud)

其中GetValue定义如下:

public unsafe Object GetValue(int index)
{
    if (Rank != 1)
       throw new ArgumentException(Environment.GetResourceString("Arg_Need1DArray"));
    Contract.EndContractBlock();
    TypedReference elemref = new TypedReference();
    InternalGetReference(&elemref, 1, &index);
    return TypedReference.InternalToObject(&elemref);
}
Run Code Online (Sandbox Code Playgroud)

索引器的返回类型Object意味着将发生装箱.

所以我的问题是,当我访问T[]where T是struct 的元素时,我能确定不会发生装箱吗?

我假设编译器和/或CLR专门处理数组,并且实际上并不打扰索引器的签名.它是否正确?在某个地方有更全面的讨论吗?

Jon*_*eet 9

也就是说,在T []的情况下,索引器返回对数组内元素的引用

并不是的.更多的是没有数组的索引器 - 而是元素访问表达式表示数组访问而不是元素访问(分别是C#5规范的7.6.6.1和7.6.6.2节).

这两者之间存在非常显着的差异 - 特别是,数组访问被归类为变量,而索引器访问被归类为.

它与属性和字段之间的差异非常相似 - 它们都具有相同的访问语法,但是属性调用函数成员并返回值,而字段访问只生成变量.

所以我的问题是,当我访问T[]where T是struct 的元素时,我能确定不会发生装箱吗?

如果你访问它作为一个T[],确保万无一失.您查看的索引器仅在您将阵列视为一个时使用IList.所以如果你使用:

IList array = new int[2];
object x = array[0];
Run Code Online (Sandbox Code Playgroud)

那么是的,那就是价值......但如果你写的话

int[] array = new int[2];
int x = array[0];
Run Code Online (Sandbox Code Playgroud)

然后那不会,它根本不会访问索引器代码或GetValue方法.