简体   繁体   English

修改新收藏而不触及原始收藏

[英]Modify new collection without touching the original one

My goal is to get a copy of collection with specified item removed from it without touching the items of original collection. 我的目标是获得不删除原始收藏品的指定项目的副本。 I have the following class: 我有以下课程:

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

and the operation I am doing is: 我正在执行的操作是:

 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);
    }

ie I am removing the item from "newCollection" but the issue is that the following line: 即我从“ newCollection”中删除该项目,但问题是以下几行:

newCollection.Remove(f);

is removing the item from original collection too ie from "collection" object. 也是从原始集合中删除项目,即从“集合”对象中删除。 I want to modify "newCollection" only and not "collection". 我只想修改“ newCollection”,而不要修改“ collection”。 How can I do that? 我怎样才能做到这一点? Isn't the following line doing a deep copy: 以下行不是进行深层复制吗?

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

if so, then why the original object is affected? 如果是这样,那么为什么原始对象会受到影响?

I know I can achieve my goal via this line too: 我知道我也可以通过以下路线实现目标:

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

but I am in dilemma about the Remove stuff and deep copy stuff happening above. 但是我对以上发生的“删除”和“深层复制”内容感到困惑。

This is because of the behaviour of the Collection<T>(IList<T>) constructor : 这是因为Collection<T>(IList<T>)构造函数的行为

The elements of the list are not copied. 列表中的元素不会被复制。 The list is wrapped by the collection, so that subsequent changes to the elements of the list are visible through the Collection. 该列表由集合包装,因此可以通过集合看到对该列表元素的后续更改。

If you want a shallow copy of the collection 1 , you could use List<T> instead: 如果您想要集合1的浅表副本,则可以使用List<T>代替:

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

(It's a little odd to see Collection<T> used like this at all. It's normally used as the base class for other generic collections.) (看到Collection<T>像这样使用是有点奇怪的。它通常用作其他泛型集合的类。)


1 It's a shallow copy because it's just copying the value of each element as a reference, rather than cloning each Foo object. 1这是一个浅表副本,因为它只是复制每个元素的值作为参考,而不是克隆每个Foo对象。 If you wrote: 如果您写了:

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

... it would still print "Hello!". ...它仍然会打印“ Hello!”。 Creating a wrapper around an existing collection isn't really creating a copy at all, shallow or deep. 围绕现有集合创建包装实际上根本不是创建浅表深表的副本。

您需要克隆它,newCollection仅是对原始集合的引用。

Collection<Foo>(collection) wrapps only the provided collection, so that any changes to the collection also effect the original collection. Collection<Foo>(collection)仅包装提供的集合,因此对集合的任何更改也会影响原始集合。

You should use a List<Foo> to do what you want, cause constructor of List<T>(IEnumerable<T>) copies the values from the original 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);
    }

You could try doing this instead. 您可以尝试这样做。

  var newCollection = new Collection<Foo>();

collection.ToList().ForEach(x => newCollection.Add(x));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 缓存集合并对其进行过滤,而无需在ASP.NET中修改原始缓存集合 - Cache collection and filter it without modify original cached collection in ASP.NET 如何使用 SelectMany 修改原始集合 - How to modify original collection using SelectMany 新列表更新原始列表 - New list updates original one 修改通用列表中的多个条目(而不必为每个条目创建一个新变量) - Modify multiple entries in a generic list (without having to create a new variable for each one) 为什么ToList可以在不重新分配自身的情况下修改原始值? - Why can ToList modify original value without reassigning to itself? 将List传递给方法,修改方法中的列表而不影响“原始” - Passing a List into a method, modify the list within the method without affecting 'original' 在不触摸数据源的情况下将新项目添加到Windows窗体应用程序组合框 - Adding a new item to a windows form application combo box without touching the datasource 如何有效地在ViewModel中修改集合? - How can one efficiently modify a collection within a ViewModel? 在操作中执行操作以进行收集而不创建新收集 - Executing Actions within Actions for collection without creating new collection 将IEnumurable转换为Observable集合,而无需创建Observable集合的新实例 - Convert IEnumurable to Observable Collection without creating new instance of Observable collection
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM