Почему "null" Nullable <t> есть хеш-код?

Немного странный вопрос...

Но может ли кто-нибудь дать мне обоснование, почему это ожидалось бы поведением?

Мне это кажется совершенно странным...

//Makes perfect sense
object o = null;
o.GetHashCode().Dump();

NullReferenceException: Ссылка на объект не установлена в экземпляр объекта.

//Seems very odd
int? i = null;
i.GetHashCode().Dump();

0

Это, очевидно, означает:

int? zero = 0;
int? argh = null;

zero.GetHashCode() == argh.GetHashCode(); //true

Ответ 1

Дело здесь в том, что

int? i = null;

не создает переменную i которая является null, но (путем выполнения неявного приведения) экземпляр Nullable<int> который не имеет значения.
Это означает, что объект/экземпляр не является null (и поскольку Nullable<T> является типом struct/value, он фактически не может быть null) и поэтому должен возвращать хэш-код.

Это также описано здесь:

Хэш-код объекта, возвращаемого свойством Value, если свойство HasValue имеет значение true, или ноль, если свойство HasValue является ложным.

Ответ 2

int? на самом деле просто сокращенно для Nullable<int>, структуры, которая обертывает тип int, чтобы позволить ему быть нулевым. Nullable может использоваться с любым типом значения.

Поскольку Nullable на самом деле является структурой (он не может быть нулевым), он должен что-то возвращать для хеш-кода, и обычно он возвращает хэш-код значения (предположительно, чтобы быть максимально прозрачным для значения внутри). Когда значение равно null, оно жестко запрограммировано на возврат 0 по умолчанию:

public override int GetHashCode() {
    return hasValue ? value.GetHashCode() : 0;
}

См. Здесь.

Ответ 3

Это похоже на документальное поведение Nullable<T>.GetHashCode(), поскольку в документации написано:

Хэш-код объекта, возвращаемого свойством Value, если свойство HasValue имеет значение true, или ноль, если свойство HasValue является ложным.