2

私の目標は、元のコレクションのアイテムに触れることなく、指定されたアイテムが削除されたコレクションのコピーを取得することです。私は次のクラスを持っています:

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

私が行っている操作は次のとおりです。

 var collection = new Collection<Foo>
                         {
                             new Foo {Name = "Name1"},
                             new Foo {Name = "Name2"},
                             new Foo {Name = "Name3"},
                             new Foo {Name = "Name4"}
                         };
    var newCollection = new Collection<Foo>(collection);

    Foo f = collection.FirstOrDefault(x => x.Name == "Name2");
    if (f != null)
    {
        newCollection.Remove(f);
    }

つまり、「newCollection」からアイテムを削除していますが、問題は次の行です。

newCollection.Remove(f);

元のコレクション、つまり「コレクション」オブジェクトからもアイテムを削除しています。「コレクション」ではなく、「newCollection」のみを変更したい。どうやってやるの?次の行はディープ コピーを実行していませんか。

 var newCollection = new Collection<Foo>(collection);

もしそうなら、なぜ元のオブジェクトが影響を受けるのですか?

この行でも目標を達成できることはわかっています。

var newCollection = collection.Where(x => x.Name != "Name2");

しかし、私は上で起こっている削除と深いコピーについてジレンマに陥っています。

4

4 に答える 4

3

これは、Collection<T>(IList<T>)コンストラクターの動作によるものです。

リストの要素はコピーされません。リストはコレクションによってラップされるため、リストの要素に対するその後の変更はコレクションを通じて表示されます。

コレクション1の浅いコピーが必要な場合は、List<T>代わりに次を使用できます。

List<Foo> newCollection = new List<T>(collection);

(このように使用されているのを見るのは少し奇妙Collection<T>です。通常、他の汎用コレクションの基本クラスとして使用されます。)


1Foo各オブジェクトのクローンを作成するのではなく、各要素の値を参照としてコピーするだけなので、浅いコピーです。あなたが書いた場合:

newCollection[0].Name = "Hello!";
Console.WriteLine(collection[0]);

...それでも「Hello!」と表示されます。既存のコレクションのラッパーを作成することは、実際には、浅いまたは深いコピーを作成することではありません。

于 2013-03-07T07:31:58.447 に答える
1

複製する必要があります。newCollection は元のコレクションへの参照にすぎません。

于 2013-03-07T07:29:17.177 に答える
0

Collection<Foo>(collection)提供されたコレクションのみをラップするため、コレクションへの変更は元のコレクションにも影響します。

を使用しList<Foo>て必要な処理を実行し、コンストラクターにList<T>(IEnumerable<T>)元のコレクションから値をコピーさせる必要があります。

var collection = new Collection<Foo>
                         {
                             new Foo {Name = "Name1"},
                             new Foo {Name = "Name2"},
                             new Foo {Name = "Name3"},
                             new Foo {Name = "Name4"}
                         };
    var newCollection = new List<Foo>(collection);

    Foo f = collection.FirstOrDefault(x => x.Name == "Name2");
    if (f != null)
    {
        newCollection.Remove(f);
    }
于 2013-03-07T07:31:16.310 に答える
0

代わりにこれを試してみてください。

  var newCollection = new Collection<Foo>();

collection.ToList().ForEach(x => newCollection.Add(x));
于 2013-03-07T07:31:30.670 に答える