Как я могу удалить несколько элементов из объекта, который является копией другого объекта, не затрагивая тот, который является производным? - PullRequest
1 голос
/ 03 октября 2011

помогите мне, пожалуйста, использовать функцию «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;
    });

Спасибо всем.

Ответы [ 3 ]

2 голосов
/ 03 октября 2011

Строка:

var anotherService = services;

просто определяет новую переменную и присваивает существующее значение (почти наверняка, ссылку на класс) этой переменной;новый объект не создается.Любой членский доступ по ссылке будет идти к тому же реальному объекту, независимо от того, какую переменную вы используете (есть только один объект).

Чтобы сделать то, что вам нужно, выпотребуется создать неглубокий или глубокий клон (в зависимости от того, что точно вы хотите получить).

Мелкий клон довольно легко сделать, вручную добавив метод Clone() или аналогичный(возможно ICloneable), который копирует свойства (отмечая, что в случае списков обычно создается новый список с теми же данными).Глубокий клон сложнее - обычный чит для сериализации и десериализации элемента.

2 голосов
/ 03 октября 2011

Сериализационный подход можно найти здесь в этот ответ :

Для справки я разместил его здесь.

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);
 }
}
1 голос
/ 03 октября 2011

Ваша проблема в том, что вы меняете один и тот же объект, просто по другой ссылке.вам нужно убедиться, что вы удаляете элементы из другого объекта, который содержит копии той же информации.Есть несколько способов сделать это.Самое простое - просто создать 2 объекта:

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