IEqualityComparer <T>и пользовательский тип - PullRequest
0 голосов
/ 09 марта 2012

Я пытаюсь сравнить пользовательский тип в два List<T> и использовать метод Intersect / Except. Равенство определяется тремя полями этого типа. Равенство основано на более чем обычном условии (все поля содержат одинаковые данные). Я реализовал конечно IEqualityComparer<T>. Моя проблема в том, что метод GetHashCode() возвращает не равное значение, если хэш-код не совпадает, и это мне не помогает, поскольку в моем случае это не так.

Есть ли способ сравнить два пользовательских объекта, когда равенство основано на более чем одном условии, поэтому я могу использовать пересечение / исключая / отличное и т.д. ...?

Вот мой код:

public bool Equals(ComparableObject x, ComparableObject y)
{
    if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
        return false;

    if (Object.ReferenceEquals(x, y))
        return true;

    if (x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return false;

    if (x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return true;


    if (!x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return false;

    if (!x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
        return true;

    if (x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
        return false;

    if (!x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
        return false;

    if (!x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return false;


    return x.Var1.Equals(y.Var1) && x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3);
}


public int GetHashCode(ComparableObject x)
{
    return obj.Var1.GetHashCode() ^ obj.Var2.GetHashCode()^ obj.Var3.GetHashCode()
}

Ответы [ 2 ]

2 голосов
/ 09 марта 2012

Ваша задача предоставить такие GetHashCode(), что возвращаемое значение будет другим для объектов, которые различаются (во всех возможных случаях; вы все равно можете вернуть один и тот же хэш-код дляодинаковые объекты) и всегда будет одинаковым для объектов, которые могут быть равными (во всех случаях; вы не можете возвращать разные хэш-коды для одинаковых объектов).

Например, если один изтри поля, которые вы сравниваете, это int, вы можете вернуть это поле как GetHashCode().

Если, однако, трудно придумать что-нибудь умное, вы можете вернуть константу, такую ​​как 42.Таким образом, Equals() будет вызываться для всех пар объектов, обеспечивая ожидаемые результаты, хотя и с наименьшей производительностью.

0 голосов
/ 09 марта 2012

Не уверен, если у вас есть другие проблемы с GetHashCode в ваших базовых типах, но это пример пользовательского типа и IEqualityComparer, который возвращает true, если только первые два поля совпадают. Это позволит Except и т. Д. Работать с типом.

    public class CustomType
    {
        public int Val1 { get; set; }
        public int Val2 { get; set; }
        public int Val3 { get; set; }
    }

    class CustomTypeComparer : IEqualityComparer<CustomType>
    {
        public bool Equals(CustomType x, CustomType y)
        { return x.Val1 == y.Val1 && x.Val2 == y.Val2; }

        public int GetHashCode(CustomType obj)
        { return obj.Val1.GetHashCode() ^ obj.Val2.GetHashCode(); }
    }

Если ваши свойства не являются простыми типами, такими как int, вы можете использовать Equals() вместо == для сравнения объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...