Я наткнулся на факт, что индексатор 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); }
}
Где 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
является структурой, не произойдет бокс?
Я предполагаю, что компилятор и/или CLR специально обрабатывают массив и на самом деле не беспокоятся о сигнатуре индексатора. Это правильно? Где-то есть более полное обсуждение этого?
IList.SomeMethod
— это неявная реализация интерфейса. Это способ сообщить, что этот метод существует, если объект классифицируется какIList
. Он будет использоваться только в том случае, если вы специально запросите его, например. в случае индексатора((IList)someArray)[x]
. Прямой доступ к индексатору массива (например,someArray[x]
) — это другое дело, вы не найдете исходники для какого-либо метода, потому что их нет. - person Sinatr   schedule 07.09.2016