Использование части 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);
}
}