0

listAとlistBという 2 つの List< Test>を作成します。listAにデータを保存します。listAからlistBにデータをコピーします。listBのデータを変更します。listBのデータを変更すると、listAでも変更されます。これを回避することはできますか?

あなたが私を助けてくれることを願っています:o)

public class Test
{
    public string Name { get; set; }
}

static void Test()
    {
        List<Test> listA = new List<Test>();
        List<Test> listB = new List<Test>();

        listA.Add(new Test { Name = "A" });
        listB.AddRange(listA);

        //I change the data in listB and the data in listA also get changed. 
        listB.First().Name = "B";
        Console.WriteLine("listA: {0} listB: {1}", listA.First().Name, listB.First().Name);

        //Can I avoid the change of data in listA?
    }
4

4 に答える 4

8

listAオブジェクトをに追加するときは、オブジェクトをコピーする必要がありますlistB

listB.AddRange(listA.Select(t => new Test { Name = t.Name }));

現時点では、 の参照を にコピーしているだけlistAlistB、これらの参照は同じオブジェクトを指しています。listAこれが、 で変更すると、変更が に表示される理由listBです。

于 2013-01-29T20:28:15.617 に答える
1

オブジェクトの新しいインスタンスを作成する必要がありTestます。

を使用してメンバーをコピーするのを少し簡単にするために、テスト クラスに copy メソッドを追加できますMemberwiseClone。これは、各プロパティを設定するための大きな select ステートメントを必要とせずにコピーするプロパティが失われた場合に適しています。

public class Test
{
    public string Name { get; set; }

    public Test Copy()
    {
        return (Test)this.MemberwiseClone();
    }
}

次に、コード内の必要な場所で使用できます。

  List<Test> listA = new List<Test>();
  List<Test> listB = new List<Test>();
  listA.Add(new Test { Name = "A" });

  listB.AddRange(listA.Select(x => x.Copy()));
于 2013-01-29T20:53:00.543 に答える
0

より複雑なオブジェクトについては、上記のコメントで説明されているように clone メソッドを実装できます。

public Test Clone()
{
     return new Test { Name = this.Name};
}

上記のコードは次のように変更されます。

listB.AddRange(listA.Select(t => t.Clone()));

.NET には ICloneable インターフェイスもありますが、このインターフェイスの使用はお勧めしません。このインターフェースの議論を含む別の質問へのリンクを含めました。

c# で ICloneable を実装する必要があるのはなぜですか?

于 2013-01-29T21:02:24.157 に答える
0

listB の Test obj は listA の Test obj とは異なるインスタンスであるため、これも機能します。

 listA.ForEach((item) =>
    {
        listB.Add(new Test {Name = item.Name});
    });
于 2013-01-29T20:37:13.163 に答える