La domanda sollevata nella mia mente dopo il thread Is it possible to access a reference of a struct from a List to make changes? da reza.Qual è la differenza tra l'elenco <T> e gli indicizzatori di array?
Così, si consideri il seguente struct
e interface
(sicuramente non molto utile, ma solo per mostrare il problema):
public interface IChangeStruct
{
int Value { get; }
void Change(int value);
}
public struct MyStruct : IChangeStruct
{
int value;
public MyStruct(int _value)
{
value = _value;
}
public int Value
{
get
{
return value;
}
}
public void Change(int value)
{
this.value = value;
}
}
MyStruct
implementa IChangeStruct
, in modo che possiamo cambiare una copia in scatola di esso proprio nel mucchio senza unboxing e sostituendolo con uno nuovo. Questo può essere demostrated con il seguente codice:
MyStruct[] l1 = new MyStruct[]
{
new MyStruct(0)
};
Console.WriteLine(l1[0].Value); //0
l1[0].Change(10);
Console.WriteLine(l1[0].Value); //10
Ora, cambiamo array per List<T>
, vale a dire:
List<MyStruct> l2 = new List<MyStruct>
{
new MyStruct(0)
};
Console.WriteLine(l2[0].Value); //0
l2[0].Change(10);
Console.WriteLine(l2[0].Value); //also 0
Per quanto ho capito, nel primo caso l1[0]
restituito il referense alla scatola struct, mentre nel secondo - era smth altro.
Ho anche cercato di smontare questo ed ho trovato:
1) Per MyStruct[]
:
IL_0030: ldelema Utils.MyStruct IL_0035: ldc.i4.s 10 IL_0037: call instance void Utils.MyStruct::Change(int32)
2) Per List<MyStruct>
:
IL_007c: callvirt instance !0 class [mscorlib]System.Collections.Generic.List`1<valuetype Utils.MyStruct>::get_Item(int32)
IL_0081: stloc.s CS$0$0001
IL_0083: ldloca.s CS$0$0001
IL_0085: ldc.i4.s 10
IL_0087: call instance void Utils.MyStruct::Change(int32)
Ma mi sembrava essere non è pronto a interpretarlo bene.
Quindi, cosa ha restituito il List<T>
? O in che modo array e List<T>
restituiscono gli elementi per indice? O è questo solo il caso con i tipi di valore e non ha nulla a che fare con i tipi di riferimento?
P.S .: Io faccio capire che uno non deve cambiamento un'istanza tipo di valore, ma il problema descritto mi ha fatto capire, non ho mai capito quanto List<T>
e il lavoro array.
Gli array hanno questa capacità solo se indicizzati 0 e dimensionali singoli anche se corretti? (poiché 'ldelema' può funzionare solo con tali restrizioni) – Earlz