The indexer for List<T>
allows you to access the elements using properties (Methods) which makes it look like an array. You can't pass the generated method by ref
as if you wrote :
Interlocked.Increment(ref myList.GetItem.get_Item(0));
But accessing array's elements is not though an indexer. Accessing array elements is directly supported in the CLR. So array[i]
returns a variable that can be passed by ref
.
From C# Specs:
Even though the syntax for accessing an indexer element is the same as
that for an array element, an indexer element is not classified as a
variable. Thus, it is not possible to pass an indexer element as a ref
or out argument.
This is the indexer of List<T>
(which internally uses an array):
public T this[int index]
{
get
{ // some checks removed
return _items[index];
}
set { _items[index] = value;}
}
From IL Side:
Accessing an array element generates this direct IL instruction:
IL_0014: ldelem.i4
Accessing a List's element through indexer generates this:
IL_001b: callvirt instance !0 class [mscorlib]System.Collections.Generic.List`1<int32>::get_Item(int32)
So, it is the same c# syntax. But the generated IL is completely different.