Использование части GetHashCode() IEqualityComparer <T> для прямых сравнений?

Я написал класс, полученный из IEqualityComparer<T>, который отлично подходит для запроса LINQ, в котором я нуждался.

Как я понимаю, сначала вызывается GetHashCode() (fast), затем Equals() (немного медленнее), если хэш-код является таким же, для таких операций.

Однако, когда вы используете его для прямых сравнений, вручную, я использую что-то вроде

return new MyIEqualityComparer().Equals(objA,objB);

Которая отказывается от проверки равенства GetHashCode(). Есть ли способ сравнения objA - objB, который автоматически не пропускает проверку GetHashCode()?

Думаю, я надеялся, что objA.Equals() будет иметь перегрузку, которая приняла аргумент, полученный из IEqualityComparer<T>.

Ответы

Ответ 1

Вычисление хэш-кода и сравнение хэша обычно медленнее, чем сравнение для равенства напрямую. Это дополнительная работа.

Здесь существуют хэш-коды для поддержки поведения хэш-таблиц O(1). Они сопоставляют объект с числом, которое требуется для работы хеш-таблиц. Коды хэша не полезны для простого сравнения сравнений.

Просто используйте Equals.

Если вы хотите знать, как наилучшим образом реализовать свою идею (хотя это не очень хорошая идея), я бы использовал вспомогательный метод:

static bool ExperimentalEquals<T>(T a, T b, IEqualityComparer<T> c) {
 if (c.GetHashCode(a) != c.GetHashCode(b)) return false;
 return c.Equals(a, b);
}

(Только для образовательных целей.)

Вы можете подумать, что в случае кэшированного хэш-кода это может быть быстрее. Но тогда Equals мог использовать сам хэш-код кэша и короткое замыкание сравнения.

Ответ 2

Не совсем понятно, что вы здесь делаете, но вы всегда можете реализовать IEquatable<T> и делегировать на MyIEqualityComparer, таким образом используя более быстрый GetHashCode():

class My : IEquatable<My>
{
    public bool Equals(My other)
    {
        return new MyIEqualityComparer().Equals(this, other);
    }
}