linq对象相等以及如何正确覆盖它

为什么var excludes = users.Except(matches); 不排除matches

如果我希望相等比较器只使用ID那么正确的方法是什么? 例子将不胜感激。

 public class User { public int ID { get; set; } public string Name { get; set; } public override string ToString() { return ID.ToString() + ":" + Name; } } private static void LinqTest2() { IEnumerable users = new List { new User {ID = 1, Name = "Jack"}, new User {ID = 2, Name = "Tom"}, new User {ID = 3, Name = "Jim"}, new User {ID = 4, Name = "Joe"}, new User {ID = 5, Name = "James"}, new User {ID = 6, Name = "Matt"}, new User {ID = 7, Name = "Jon"}, new User {ID = 8, Name = "Jill"} }.OfType(); IEnumerable localList = new List { new User {ID = 4, Name = "Joe"}, new User {ID = 5, Name = "James"} }.OfType(); //After creating the two list var matches = from u in users join lu in localList on u.ID equals lu.ID select lu; Console.WriteLine("--------------MATCHES----------------"); foreach (var item in matches) { Console.WriteLine(item.ToString()); } Console.WriteLine("--------------EXCLUDES----------------"); var excludes = users.Except(matches); foreach (var item in excludes) { Console.WriteLine(item.ToString()); } } 

  sealed class CompareUsersById : IEqualityComparer { public bool Equals(User x, User y) { if(x == null) return y == null; else if(y == null) return false; else return x.ID == y.ID; } public int GetHashCode(User obj) { return obj.ID; } } 

然后

 var excludes = users.Except(matches, new CompareUsersById()); 

您的User类不会覆盖EqualsGetHashCode因此使用Equals的默认实现。 在这种情况下,这意味着它会比较参考。 您创建了两个具有相同值的用户对象,但由于这些是不同的对象,因此它们的比较不相等。

覆盖Equals的替代方法是使用带有IEqualityComparer的Except的重载 。