|
■No93537 (ピカチュウ さん) に返信 > var getResult=〇〇//SQLで取ったList<class>のリスト。今回は4つのリストが入ってます
提示頂いたコードは、文法違反のエラーになりそうですね。
class という名前のクラスは作れませんし、メソッドについても RemoveAt はあっても removeat はありませんので。
> どうしてこんな現象が起きるのでしょうか?
List<int> x = new List<int> { 10, 20, 30, 40 }; List<int> y = x; List<int> z = x; z.RemoveAt(0);
たとえば上記の場合、インスタンスは new List<int> ひとつだけです。 x や y や z が参照しているインスタンスは、同じものとなります。
そして RemoveAt は「インスタンス メソッド」です。
ひとつしか無いインスタンスを操作しているわけですから、 x、y、z いずれから見た場合も、その中身は { 10, 20, 30, 40 } から { 20, 30, 40 } に変化するというわけです。
もしもデータの複製が「シャローコピー」で構わない場合は、ToList を使う方法があります。
List<int> x = new List<int> { 10, 20, 30, 40 }; List<int> y = x.ToList(); List<int> z = x.ToList(); x[2] = 123; y.RemoveAt(1); z.RemoveAt(0);
.ToList() によって新しいインスタンスが生成されますので、 x、y、z が参照しているオブジェクトは、それぞれ別物となります。
x の中身は { 10, 20, 123, 40 } で、 y の中身は { 10, 30, 40 } で z の中身は { 20, 30, 40 } ですね。
ただし「ディープコピー」が必要な場合は、ToList だけでは不足です。
List<int[]> x = new List<int[]> { new int[] { 10, 20 }, new int[] { 30, 40 } }; List<int[]> y = x.ToList(); List<int[]> z = x.ToList(); x[1][0] = 111; y[0][0] = 222; z[1] = new int[] { 123, 456 };
上記を実行すると、 x の中身は { { 222, 20 }, { 111, 40 } } y の中身も { { 222, 20 }, { 111, 40 } } z の中身は { { 222, 20 }, { 123, 456 } } となります。
x,y,z はそれぞれ別のインスタンスですが、 x[0], y[0], z[0] が参照している配列は同一のインスタンスだからです。
上記を、kiku さんが紹介されていた記事にある DeepClone の実装に置き換えてみます。
List<int[]> x = new List<int[]> { new int[] { 10, 20 }, new int[] { 30, 40 } }; List<int[]> y = x.DeepClone(); List<int[]> z = x.DeepClone(); x[1][0] = 111; y[0][0] = 222; z[1] = new int[] { 123, 456 };
この場合、上記を実行した結果が x の中身は { { 10, 20 }, { 111, 40 } } y の中身も { { 222, 20 }, { 30, 40 } } z の中身は { { 10, 20 }, { 123, 456 } } となりますので、求めるものに近いのではないでしょうか?
なお、DeepClone メソッド内では Serialize / Deserialize メソッドが 利用されていますので、これが使えるのは、List<T> の T 型が シリアル化可能な型である場合に限られます。
|