我偶然发现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,并且实际上并不打扰索引器的签名。它是否正确?在某个地方有更全面的讨论吗?
答案 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
方法。