首页 > 解决方案 > 使用 except Alternative 删除重复项

问题描述

我尝试使用 Linq 获得一个例外列表,也就是说,如果存在,我想从另一个列表中减去元素列表。但以下内容不会删除重复项。

var simplifiedList = request.CountryExceptionRecords
                .Where(e => !request.CopyInitialCountryExceptionRecords
                        .Any(c =>
                                    c.PropString1 == e.PropString1
                                    && c.PropString2.Trim()  == e.PropString2.Trim()
                                    && c.PropString3 == e.PropString3));

Edit,添加.Distinct()到 final(after Where) 就像一个魅力。但我不明白为什么它会起作用,因为Records(Lists)实现所使用的类既不是方法GetHash也不是Equal方法。

标签: c#linqif-statement

解决方案


将 .Distinct() 添加到决赛(在 Where 之后)就像一个魅力。但我不明白它为什么会起作用,因为 Records(Lists) 使用的类既不实现 GetHash 也不实现 Equal 方法。

这是因为 from Distinct 不使用 LINQ to Objects

Distinct()方法检查引用类型的引用相等性。这意味着它实际上是在寻找重复的相同对象,而不是包含相同值的不同对象。

因此,让我通过示例向您展示:

foo testA = new foo() { PropString1 = "A", PropString2 = "A", PropString3 = "A" };
foo testB = new foo() { PropString1 = "B", PropString2 = "B", PropString3 = "B" };
foo testC = new foo() { PropString1 = "C", PropString2 = "C", PropString3 = "C" };

List<foo> CountryExceptionRecords = new List<foo>();
CountryExceptionRecords.Add(testA);
CountryExceptionRecords.Add(testB);
CountryExceptionRecords.Add(testC);
CountryExceptionRecords.Add(testC); //adding duplicate item

List<foo> CopyInitialCountryExceptionRecords = new List<foo>();
CopyInitialCountryExceptionRecords.Add(testA); //same object adding second list

var simplifiedList = CountryExceptionRecords
                        .Where(e => !CopyInitialCountryExceptionRecords
                                        .Any(c =>
                                            c.PropString1 == e.PropString1
                                            && c.PropString2.Trim() == e.PropString2.Trim()
                                            && c.PropString3 == e.PropString3)).Distinct().ToList();

在这种情况下,simplifiedList计数将为 2,因为列表具有具有相同引用的对象。

但另一方面,以下示例不会删除重复项,这是因为它们不是相同的对象引用,而对象具有相同的值。在这种情况下,您需要使用IEqualityComparer

List<foo> CountryExceptionRecords = new List<foo>();
CountryExceptionRecords.Add(new foo() { PropString1 = "A", PropString2 = "A", PropString3 = "A" });
CountryExceptionRecords.Add(new foo() { PropString1 = "B", PropString2 = "B", PropString3 = "B" });
CountryExceptionRecords.Add(new foo() { PropString1 = "C", PropString2 = "C", PropString3 = "C" });
CountryExceptionRecords.Add(new foo() { PropString1 = "C", PropString2 = "C", PropString3 = "C" });

List<foo> CopyInitialCountryExceptionRecords = new List<foo>();
//This is another object wheares the values are same
CopyInitialCountryExceptionRecords.Add(new foo() { PropString1 = "A", PropString2 = "A", PropString3 = "A" });

var simplifiedList = CountryExceptionRecords
                        .Where(e => !CopyInitialCountryExceptionRecords
                                        .Any(c =>
                                            c.PropString1 == e.PropString1
                                            && c.PropString2.Trim() == e.PropString2.Trim()
                                            && c.PropString3 == e.PropString3)).Distinct().ToList();

推荐阅读