List<構造> の値フィールド割り当てのエラー報告に対する C# ソリューション
1. エラー分析
//定义结构体
public struct MyStruct
{
public float a;
public float b;
}
//报错场景复现
void Main()
{
List<MyStruct> list = new List<MyStruct>();
list.Add(new MyStruct());
list[0].a = 5; //这句编译器会报错
}
- 上記の list[0].a = 5; はエラーを報告します。エラーは次のとおりです
。 インデクサー アクセスは一時的な値を返します。アクセス時に構造体メンバーを変更できません。
これは、 list[0] がオブジェクトへの参照ではなく、オブジェクトのコピーを返すためです。
list[0].a = 5 を実行すると、実際にはコピーの値の型が変更されますが、実際の参照の値は予想どおりに変更できません。これは無意味であるため、コンパイラはエラーをスローします。
2、解決策
1: 一時コピーを変更し、最後にそれを元に戻します
- これは最も実用的な方法で、最初に list[i] を使用してコピーを取得し、そのコピーを変更します。最後に、次のコードのように設定を戻します。
//先拿到副本
MyStruct myStruct = list[0];
//做一些赋值操作
myStruct.a = 5;
...
//最后再设置回来
list[0] = myStruct;
2: 構造をクラスに変更する
- 構造をクラスに変更すれば、それほど多くのことはなくなります。しかし、これはあまり良いことではありません。その構造は設計で使用されているので、何らかの理由があるはずであり、この問題のためにそれを元に戻すのは良くありません。
3: 構造体の値フィールドを参照フィールドにカプセル化します。
//把a封装在类里
public class MyClass
{
public int a;
}
public struct MyStruct
{
public MyClass myClass;
public float b;
}
void Main()
{
List<MyStruct> list = new List<MyStruct>();
list.Add(new MyStruct());
list[0].myClass.a = 5;
}
これに変更することもできますが、それでも面倒です。最初の方法を使用することをお勧めします。
3. 公式参考文書
最後に、公式リファレンス ドキュメントを添付します。興味のある方は
コンパイラ エラー CS1612を参照してください。