構造体のDictionaryでは直接値を変更できない
コンテナの返値が値型か参照型かに気をつけましょうねという話。
シチュエーション
例えば、以下のようなコードを書いてみたとする。
public class Program { struct MyStruct { public int val1; public int val2; } public static void Main() { var dic = new Dictionary<int, MyStruct>(); dic[0].val1 = 1; dic[0].val2 = 2; } }
自前の構造体をDictionaryに格納し、その値を変更するコードである。
しかし、これはコンパイルエラーになる。
error CS1612: 変数ではないため、'Dictionary.this[int]' の戻り値を変更できません
Dictionary内の要素に値を代入することができていないようだ。
dic[0]の返値は参照型ではなく値型
実は、これはMyStructが値型であることが原因である。
つまり、dic[0]というのは、dic内の0番目の要素のコピーであって、それに対していかなる操作を行ってもdic内の要素には一切影響しない。
上記のように[]で参照したものの値を直接書き換えたいならば、MyStructをclassにするしかない。
public class Program { class MyStruct { public int val1; public int val2; } public static void Main() { var dic = new Dictionary<int, MyStruct>(); dic.Add(0, new MyStruct()); dic[0].val1 = 1; dic[0].val2 = 2; } }
これならdic[0]はdic内の0番目の要素への参照となり、正しく動く。
C++ならコンテナは必ず参照型を返してくれるので、原因が分かるのに時間がかかった。