Разница между string.GetHashCode и IEqualityComparer <string> .Default.GetHashCode

1

Я хотел бы использовать Distinct() с моими данными, объявленными как IEnumerable<KeyValuePair<IdentType, string>>. В этом случае я должен реализовать свой собственный IEqualityComparer и есть мой вопрос:

Есть ли разница между нижеприведенными реализациями?

public int GetHashCode(KeyValuePair<IdentType, string> obj) {
    return EqualityComparer<string>.Default.GetHashCode(obj.Value);
}

а также

public int GetHashCode(KeyValuePair<IdentType, string> obj) {
    return obj.Value.GetHashCode();
}
Теги:

4 ответа

4

Между вашими двумя методами существует только небольшая разница.

EqualityComparer<string>.Default вернет класс типа GenericEqualityComparer<T> если класс implments IEquateable<T> (какая строка). Так что GetHashCode(obj.Value) получает вызов

    public override int GetHashCode(T obj) {
        if (obj == null) return 0;
        return obj.GetHashCode();
    }

который является тем же самым, что вы вызываете obj.Value.GetHashCode(); напрямую, за исключением того факта, что если у вас есть нулевая строка, то по умолчанию сопоставитель вернет 0, а версия прямого вызова будет выбрана исключение с нулевой ссылкой.

2

Одно из отличий заключается в том, что EqualityComparer<string>.Default.GetHashCode не будет разбиваться, когда вы передадите ему null.

using System;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        var n = EqualityComparer<string>.Default.GetHashCode(null);
        Console.WriteLine(n);
    }
}

Кроме того, результаты будут идентичными по дизайну, потому что System.String реализует IEquatable<System.String>

Свойство Default проверяет, реализует ли тип T общий интерфейс System.IEquatable<T> и, если это так, возвращает EqualityComparer<T> который вызывает реализацию метода IEquatable<T>.Equals. В противном случае он возвращает EqualityComparer<T>, как это предусмотрено T

1

Нет. Это не так. Реализация будет такой же, поскольку оба они называют GetHashCode() для фактического класса, в этом случае string.

В конце концов, метод CreateComparer внутри EqualityComparer создает GenericEqualityComparer, а реализация его GetHashCode:

public override int GetHashCode(T obj) {
    if (obj == null) return 0;
    return obj.GetHashCode();
}

В этом случае obj будет исходной string которой в противном случае вы могли бы вызвать GetHasCode. Единственный случай, который заставит его вести себя по-другому, - это когда ваша string равна null.

1

Только один: сопоставитель равенства GetHashCode вернет 0, если строка равна нулю, тогда как вторая реализация вызовет исключение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню