How are the Indexers are defined in List and Arrays.
List where MyStruct is a Structure.
The final point:
lists[0]._x=5
is actually just a restatement of your earlier point:
arr[0]gives a reference to the first Structure item.Butlists[0]gives me a copy of it.
If you edited a copy of it, the change would be lost into the ether, i.e.
var throwawayCopy = lists[0];
throwawayCopy._x = 5;
// (and never refer to throwawayCopy again, ever)
Since that is almost certainly not what you intended, the compiler doesn't let you. However, mutable structs are evil. A better option here would be don't use mutable structs. They bite.
Taking this down a level, to a simple but concrete example:
using System;
struct Evil
{
public int Yeuch;
}
public class Program
{
public static void Main()
{
var pain = new Evil[] { new Evil { Yeuch = 2 } };
pain[0].Yeuch = 27;
Console.WriteLine(pain[0].Yeuch);
}
}
This compiles (looking at the last 2 lines here) as:
L_0026: ldloc.0 <== pain
L_0027: ldc.i4.0 <== 0
L_0028: ldelema Evil <== get the MANAGED POINTER to the 0th element
(not the 0th element as a value)
L_002d: ldc.i4.s 0x1b <== 27
L_002f: stfld int32 Evil::Yeuch <== store field
L_0034: ldloc.0 <== pain
L_0035: ldc.i4.0 <== 0
L_0036: ldelema Evil <== get the MANAGED POINTER to the 0th element
(not the 0th element as a value)
L_003b: ldfld int32 Evil::Yeuch <== read field
L_0040: call void [mscorlib]System.Console::WriteLine(int32) <== writeline
L_0045: ret
It never actual talks to the struct as a value - no copies, etc