如何从一个对象(该对象是另一个对象的副本)中删除多个项,而不影响派生的对象

本文关键字:对象 一个对象 派生 影响 删除 副本 | 更新日期: 2023-09-27 18:10:29

请帮助我使用函数"RemoveAll"或者应该有另一种实现。我有一个对象(services),它包含一个项目列表。我创建了另一个对象(anotherService),它与第一个对象相等。

我应该从第二个对象(anotherService)中删除mainService == false的项。

我使用了"RemoveAll"函数,但是在执行了这个操作之后,对象(services)中mainService = false的项也被删除了。我需要让第一个对象完成它在移除之前的样子。

var services = DictionaryObject.GetDictionaryValidatedByDate<ServiceInfo>(DictionaryType.REF_SERVICE, DateTime.Now);
var anotherService = services;
anotherService.RemoveAll(p =>                
    {                   
        if (p.Model.mainService == false)
        {
           return true;
        }
        return false;
    });

如何从一个对象(该对象是另一个对象的副本)中删除多个项,而不影响派生的对象

一行:

var anotherService = services;

简单地定义一个新变量,并将现有值(几乎可以肯定是类引用)赋给该变量;没有创建新的对象。对引用的任何成员访问都将访问到相同的实际对象,无论您使用哪个变量(只有一个对象)。

要做您需要的事情,您需要创建一个浅克隆或深克隆(取决于您想要发生的是什么)。

通过手动添加复制属性的Clone()方法或类似方法(可能是ICloneable)来实现浅克隆非常容易(注意,在列表的情况下,通常创建具有相同数据的列表)。深度克隆更棘手——一种常见的欺骗手段是序列化和反序列化条目。

序列化方法可以在这个答案中找到:

我把它贴在这里供参考。

public static T DeepClone<T>(T obj)
{
 using (var ms = new MemoryStream())
 {
   var formatter = new BinaryFormatter();
   formatter.Serialize(ms, obj);
   ms.Position = 0;
   return (T) formatter.Deserialize(ms);
 }
}

您的问题是您正在更改相同的对象,只是通过不同的引用。您需要确保从包含相同信息副本的不同对象中删除了项。有几种方法可以做到这一点。最简单的是创建两个对象:

var services = DictionaryObject.GetDictionaryValidatedByDate<ServiceInfo>(DictionaryType.REF_SERVICE, DateTime.Now);
var anotherService =  DictionaryObject.GetDictionaryValidatedByDate<ServiceInfo>(DictionaryType.REF_SERVICE, DateTime.Now);;
anotherService.RemoveAll(p =>                
    {                   
        if (p.Model.mainService == false || p.Model.mainService == true)
        {
           return true;
        }
        return false;
    });

或者你可以复制/克隆你的对象像这样:

var anotherService = services.Copy(); //or maybe use a copy constructor here instead:
//  var anotherService = new ServiceInfo(sevices);
anotherService.RemoveAll(p =>                
{                   
    if (p.Model.mainService == false || p.Model.mainService == true)
    {
       return true;
    }
    return false;
});

当你实现Copy()方法或构造函数时,需要复制对象,你需要确保你创建了字典的副本,而不是只使用对同一个字典的引用。

如果返回的对象只是一个IDictionary<K,V>(从提供的代码中不清楚),您可以这样做:

var anotherService = new Dictionary<KeyType,ValueType>(services)
anotherService.RemoveAll(p =>                
{                   
    if (p.Model.mainService == false || p.Model.mainService == true)
    {
       return true;
    }
    return false;
});