如何从对象中删除多个项目,这些项目是另一个对象的副本,而不会影响其中一个项目的派生?

时间:2011-10-03 13:56:20

标签: c# removeall

请帮我使用“RemoveAll”功能,或者应该有其他实现。 我有一个对象(服务),其中包含一个包含项目的列表。 我创建了另一个与第一个对象相同的对象( 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;
    });

谢谢大家。

3 个答案:

答案 0 :(得分:2)

该行:

var anotherService = services;

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

要做你需要的,你需要创建一个浅或深的克隆(取决于你想要发生的完全)。

通过手动添加复制属性的Clone()方法或类似方法(可能是ICloneable),很容易做到浅层克隆(注意在列表的情况下, new < / em>通常会创建具有相同数据的列表)。深度克隆是比较棘手的 - 一个常见的欺骗是序列化和反序列化项目。

答案 1 :(得分:2)

序列化方法可以在this answer

中找到

作为参考,我已在此处发布。

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

答案 2 :(得分:1)

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

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