リストから構造体の参照にアクセスして変更を加えることは可能ですか? スレッドバイレザ。
したがって、次のことを考慮してstruct
くださいinterface
(間違いなくあまり役に立ちませんが、問題を示すためだけに):
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
を実装IChangeStruct
しているため、ボックス化されたコピーを、ボックス化を解除して新しいものに置き換えることなく、ヒープ内で直接変更できます。これは、次のコードで実証できます。
MyStruct[] l1 = new MyStruct[]
{
new MyStruct(0)
};
Console.WriteLine(l1[0].Value); //0
l1[0].Change(10);
Console.WriteLine(l1[0].Value); //10
それでは、配列を に変更しましょうList<T>
。
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
私が理解している限り、最初のケースでl1[0]
はボックス化された構造体への参照を返しましたが、2番目のケースではそうではありませんでした。
これも分解しようとしましたが、次のことがわかりました。
1) の場合MyStruct[]
:
IL_0030: ldelema Utils.MyStruct IL_0035: ldc.i4.s 10 IL_0037: call instance void Utils.MyStruct::Change(int32)
2) の場合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)
しかし、私はそれをうまく解釈する準備ができていないようでした。
それで、何をList<T>
返しましたか?List<T>
または、要素を配列してインデックスで返すにはどうすればよいでしょうか? それとも、これは値型の場合のみであり、参照型とは関係ありませんか?
PS:値型のインスタンスを変更してはならないことは理解していますが、説明されている問題により、配列がどのように機能するかを理解できませんでした。List<T>