【C#】ToList()の挙動についての勘違い
ToList()が思ってた動作と違ったのでメモしておきます。
↓のようなクラスを作ります。
class MyClass { public MyClass() { var random = new Random(); Value = random.Next(100); } public int Value { get; set; } }
上記クラスを使って以下のようなコードを書いてしまっていました。 ToList()は新しいリストを作成するので、中身もコピーされると勝手に勘違いしてました。
var myClasses = new List<MyClass>(); for (int i = 0; i < 1000; ++i) { myClasses.Add(new MyClass()); } // リストからある条件を満たすものを取り出し、コピーしたつもりになっていた var selectedMyClasses = myClasses.Where(i => i.Value >= 50).ToList(); // 値を書き換えると selectedMyClasses[0].Value = 10000; // 元の中身が書き換わってるので、countは1と表示される int count = myClasses.Count(i => i.Value == 10000); Console.WriteLine(count);
中身もコピーしたいのであれば、MyClassにコピー用メソッドを加えて
class MyClass : ICloneable { public MyClass() { var random = new Random(); Value = random.Next(100); } public int Value { get; set; } public object Clone() { return MemberwiseClone(); } }
↓こんな感じに書くのでしょうか。。。
var myClasses = new List<MyClass>(); for (int i = 0; i < 1000; ++i) { myClasses.Add(new MyClass()); } var selectedMyClasses = myClasses.Where(i => i.Value >= 50).Select(i => (MyClass)i.Clone()).ToList(); selectedMyClasses[0].Value = 10000; int count = myClasses.Count(i => i.Value == 10000); Console.WriteLine(count);
当たり前という突っ込みを受けそうですが、他に同じ質問している人いたので若干ほっとしました。