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

时间:2016-09-07 14:54:48

标签: c# .net arrays list indexer

我偶然发现fact索引器this[int index] { get; }对于结构数组的工作方式与对结构列表的工作方式不同。也就是说,在T[]的情况下,索引器返回对数组中元素的引用,而在List<T>的情况下,索引器返回元素的副本。

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

然而,我对实际实施感到困惑。因此,.net参考源中Array的{​​{3}}读取:

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

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);
}

索引器的返回类型是Object,这意味着将进行装箱。

所以我的问题是,当我访问T[] T是一个结构的DelegatingHandler元素时,我能确定不会发生装箱吗?

我假设编译器和/或CLR特别对待Array,并且实际上并不打扰索引器的签名。它是否正确?在某个地方有更全面的讨论吗?

1 个答案:

答案 0 :(得分:9)

  

即,在T []的情况下,索引器返回对数组中元素的引用

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

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

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

  

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

如果您正在 IList方式访问,请确保。您查看的索引器仅在您将阵列视为IList array = new int[2]; object x = array[0]; 时使用。所以如果你使用:

int[] array = new int[2];
int x = array[0];

然后是的,那将把价值包装好......但如果你写的话

GetValue

然后不会,它根本不会访问索引器代码或ONBUILD WORKDIR /app/src方法。