使用Linq除了不按我的想法工作

List1包含项{ A, B }List2包含项{ A, B, C }

我需要的是当我使用Except Linq扩展时返回{ C } 。 相反,我得到了返回{ A, B } ,如果我在表达式中翻转列表,结果是{ A, B, C }

我是否误解了Except的观点? 还有其他我没有看到使用的扩展吗?

到目前为止,我已经查看并尝试了很多不同的post,但没有成功。

 var except = List1.Except(List2); //This is the line I have thus far 

编辑:是的我正在比较简单的对象。 我从未使用过IEqualityComparer ,了解它很有趣。

谢谢大家的帮助。 问题不是实现比较器。 链接的博客文章和下面的示例有帮助。

如果要在列表中存储引用类型,则必须确保有一种方法可以比较对象是否相等。 否则,将通过比较它们是否引用相同的地址来检查它们。

您可以实现IEqualityComparer并将其作为参数发送到Except()函数。 这是一篇你可能会发现有用的博客文章 。

你只是混淆了参数的顺序。 我可以看到这种混乱出现的地方,因为官方文档没有那么有用:

通过使用默认的相等比较器来比较值,生成两个序列的集合差异。

除非你精通集合论,否则可能并不清楚实际上是什么设置差异 – 它不仅仅是集合之间的不同之处。 实际上, Except返回第一组中不在第二组中的元素列表。

试试这个:

 var except = List2.Except(List1); // { C } 

所以只是为了完整……

 // Except gives you the items in the first set but not the second var InList1ButNotList2 = List1.Except(List2); var InList2ButNotList1 = List2.Except(List1); // Intersect gives you the items that are common to both lists var InBothLists = List1.Intersect(List2); 

编辑:由于您的列表包含对象,您需要为您的类传入IEqualityComparer …以下是基于组合对象的示例IEqualityComparer的外观… 🙂

 // Except gives you the items in the first set but not the second var equalityComparer = new MyClassEqualityComparer(); var InList1ButNotList2 = List1.Except(List2, equalityComparer); var InList2ButNotList1 = List2.Except(List1, equalityComparer); // Intersect gives you the items that are common to both lists var InBothLists = List1.Intersect(List2); public class MyClass { public int i; public int j; } class MyClassEqualityComparer : IEqualityComparer { public bool Equals(MyClass x, MyClass y) { return xi == yi && xj == yj; } public int GetHashCode(MyClass obj) { unchecked { if (obj == null) return 0; int hashCode = obj.i.GetHashCode(); hashCode = (hashCode * 397) ^ obj.i.GetHashCode(); return hashCode; } } } 

仅供参考:我想比较连接并可用于系统的USB驱动器。

所以这是实现IEqualityComparer接口的类

 public class DriveInfoEqualityComparer : IEqualityComparer { public bool Equals(DriveInfo x, DriveInfo y) { if (object.ReferenceEquals(x, y)) return true; if (x == null || y == null) return false; // compare with Drive Level return x.VolumeLabel.Equals(y.VolumeLabel); } public int GetHashCode(DriveInfo obj) { return obj.VolumeLabel.GetHashCode(); } } 

你可以像这样使用它

 var newDeviceLst = DriveInfo.GetDrives() .ToList() .Except(inMemoryDrives, new DriveInfoEqualityComparer()) .ToList();