2017-01-03 6 views
0

я получил следующий кодКак создать новый список объектов при удалении дубликатов?

List<RRProcess> noDuplicates = pSorted 
    .GroupBy(i => i.pID) 
    .Select(group => group.First()) 
    .ToList(); 

Проблема заключается в том, что если я что-то изменить в noDuplicates, это изменит его в pSorted, а также. Я прочитал все сообщения о том, как создать новый список, но все же не могу понять это в моем случае, как мне это сделать.

Итак, вопрос в том, как создать новый список из элементов pSorted без дублирования объектов, имеющих один и тот же идентификатор PID?

спасибо

+0

'RRProcess' это класс, поэтому ссылочный тип. Вот почему вы меняете элементы в обоих коллекциях. Вам нужно создать новые экземпляры, создав экземпляр-конструктор или назначив все свойства вручную. –

+0

Вы создаете новый список при использовании 'ToList()', я думаю, вы хотите создать «копию» элементов в списке, не так ли? – Fabio

+0

Итак, вы хотите иметь возможность делать что-то вроде 'noDuplicates [0] .Property = 5;' и исходный объект в pSorted не должен отражать это изменение? Если это так, вам придется клонировать объекты в некотором роде. В его нынешнем виде это один и тот же объект в обоих списках, поэтому единственный способ получить то, что вы хотите, состоит в том, чтобы иметь разные объекты в каждом списке. – Chris

ответ

6

Вам нужно будет создать новые объекты, если вы хотите предотвратить это. Существует несколько способов, например. используйте ICloneable или создайте новые объекты самостоятельно.

Если класс реализует ICloneable:

List<RRProcess> noDuplicates = pSorted 
    .GroupBy(i => i.pID) 
    .Select(group => (RRProcess) group.First().Clone()) 
    .ToList(); 

Или, если у него есть конструктор, который позволяет сделать копию с оригинала:

List<RRProcess> noDuplicates = pSorted 
    .GroupBy(i => i.pID) 
    .Select(group => new RRProcess(group.First())) 
    .ToList(); 

или используя конструктор без параметров + инициализатор объекта:

List<RRProcess> noDuplicates = pSorted 
    .GroupBy(i => i.pID) 
    .Select(group => group.First()) 
    .Select(x => new RRProcess { pID = x.pID /* etc for other properties */ }) 
    .ToList(); 

Обратите внимание, что создание копии - неважно как - может быть сложно, например. если у оригинала есть коллекция, вы можете обнаружить, что скопированный объект должен получить копию этой коллекции, а не просто новую ссылку на эту же старую коллекцию. Это называется глубоким клонированием. Оба могут работать, это зависит от того, нужно это вам или нет.

+0

Ваше предложение «ICloneable» не будет работать, потому что ему не прислано «RRProcess». – Bauss

+0

Исправлено, спасибо, что поймали это. –

+0

спасибо, ваша помощь очень ценится! : D –

3

Это не может быть сделано непосредственно в LINQ, для этого требуется дополнительный код с вашей стороны.

Если ваши объекты (. В этом случае RRProcess) не имеет членов, которые являются объектами, то вы можете реализовать метод клонирования для вашего объекта, как показано ниже:

public RRProcess Clone() 
    { 
     return this.MemberwiseClone(); 
    } 

Замечу, что MemberwiseClone будет производят только мелкий клон, поэтому он не будет клонировать объекты.

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

Смотрите этот ответ: https://stackoverflow.com/a/129395/2026276

Вы можете использовать выше для реализации ICloneable смотрите: https://msdn.microsoft.com/en-us/library/system.icloneable(v=vs.110).aspx

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

Что вы тогда можете сделать это:

List<RRProcess> noDuplicates = pSorted 
    .GroupBy(i => i.pID) 
    .Select(group => group.First().Clone()) 
    .ToList(); 

Если вы реализуете ICloneable

List<RRProcess> noDuplicates = pSorted 
    .GroupBy(i => i.pID) 
    .Select(group => (RRProcess)group.First().Clone()) 
    .ToList(); 
Смежные вопросы