简体   繁体   English

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

[英]linq object equality and how to properly override it

Why is var excludes = users.Except(matches); 为什么var excludes = users.Except(matches); not excluding the matches ? 不排除matches

What is the proper way if I want the equality comparer to use only the ID ? 如果我希望相等比较器只使用ID那么正确的方法是什么? Examples would be appreciated. 例子将不胜感激。

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<User> users = new List<User>
    {
        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<User>();

    IEnumerable<User> localList = new List<User>
    {
        new User {ID = 4, Name = "Joe"},
        new User {ID = 5, Name = "James"}
    }.OfType<User>();


    //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<User>
    {
        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;
        }
    }

and then 接着

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

Your User class doesn't override Equals and GetHashCode so the default implementation of Equals is used. 您的User类不会覆盖EqualsGetHashCode因此使用Equals的默认实现。 In this case this means it compares the references. 在这种情况下,这意味着它会比较参考。 You have created two user objects with the same values, but because these are differenct objects they compare unequal. 您已经创建了两个具有相同值的用户对象,但由于这些是不同的对象,因此它们的比较不相等。

An alternative to overriding Equals is to use the overload of Except that takes an IEqualityComparer . 覆盖Equals的替代方法是使用带有IEqualityComparer的Except重载

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM