如何在删除重复项时创建新的对象列表?

时间:2017-01-03 11:47:04

标签: c# linq

我收到了以下代码

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

问题是,如果我在noDuplicates中更改了任何内容,它也会在pSorted中更改它。 我已经阅读了有关如何创建新列表的所有帖子,但仍然无法在我的案例中弄明白,我该怎么做。

所以问题是,如何从pSorted的元素创建一个新列表,而不重复具有相同pID的对象?

感谢

2 个答案:

答案 0 :(得分: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();

请注意,创建副本 - 无论如何 - 可能会非常棘手,例如:如果原始集合有一个集合,您可能会发现复制的对象需要获取该集合的副本,而不仅仅是对该集合的新引用。这称为深度克隆。两者都可以工作,这取决于你是否需要这个。

答案 1 :(得分: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()的{​​{1}}只返回一个需要从您身边进一步投射的对象,在您的情况下可能不值得。

你可以做的是:

ICloneable

如果您实施List<RRProcess> noDuplicates = pSorted .GroupBy(i => i.pID) .Select(group => group.First().Clone()) .ToList();

ICloneable