简体   繁体   中英

How can I delete several items from an object, which is copy of another object, without affecting the one of which is derived?

help me please to use the function "RemoveAll" or maybe there should be another implementation. I have an object ( services ) which contains a list with items. I make another object ( anotherService ) which is equal with the first.

I should remove from second object ( anotherService ) items which have mainService == false.

I use the "RemoveAll" function, but after this action is made, from the object ( services ) items which are mainService = false are also removed. I need to have the first object completed how it was before removing.

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

Thank you all.

The line:

var anotherService = services;

simply defines a new variable and assigns the existing value (almost certainly a class reference) to that variable; no new object is created. Any member-access on a reference is going to go to the same actual object, no matter which variable you use (there is only one object).

To do what you need, you would need to create a shallow or deep clone (depending on what exactly you want to happen).

A shallow clone is pretty easy to do by manually adding a Clone() method or similar (maybe ICloneable ) which copies the properties (noting that in the case of lists, a new list with the same data is usually created). A deep clone is trickier - a common cheat there is to serialize and deserialize the item.

The Serialization approach can be found here in this answer :

For reference I have posted it here.

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

Your problem is that you are changing the same object, just through a different reference. you need to make sure that you removes items from a different object, which contains copies of the same information. There are a few ways you could do this. The simplest is to just create 2 objects:

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

or you could copy/clone your object something like:

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

When you implement the Copy() method or the constructor which takes the object to copy you need to make sure that you create copies of dictionaries and do not just use references to the same dictionary.

if your object being returned is just an IDictionary<K,V> (its not clear from the code provided) you may be able to do this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM