Nullable<T>
имеет немного магии компилятора, которая заставляет его выглядеть , как если бы было значение null
.Но нет.По сути, поскольку Nullable<T>
является типом значения, он не может быть null
для начала.Его обнуляемость определяется, есть ли значение или нет.Это означает, что вы можете вызвать HasValue
(что важно, так как именно это вставляет компилятор при написании num == null
) и другие методы, которые не зависят от присутствующего значения.
Что касаетсяНесколько конкретных моментов:
ToString
- это реализация, которая работает аналогично тому, как null
значения преобразуются в строку при использовании в конкатенации строк, то есть в результате получается пустая строка.Вы также не хотите, чтобы ToString
когда-либо выдавал. GetHashCode
необходимо поместить Nullable<T>
в качестве ключа в словаре или поместить их в хэш-набор.Он также не должен выдавать, поэтому должен возвращать что-то разумное, когда нет значения. - Документация объясняет немного базовых концепций.
Доступзначение, когда его нет, запрещено.Как отметили Зохар Пелед и Марк Гравелл ♦ в комментариях, это то, что неявно происходит при вызове GetType
:
Казалось бы, логично, чтокомпилятор может просто тихо заменить nullableValue.GetType()
на typeof(SomeT?)
, но тогда это будет означать, что он всегда дает запутанные ответы по сравнению с
object obj = nullableValue;
Type type = obj.GetType()
Можно ожидать, что это будет работать аналогично, но obj.GetType()
всегда будетверните либо typeof(T)
(не typeof(T?)
), либо бросьте NullReferenceException
, потому что T?
ящики либо в T
, либо в null
(и вы не можете спросить null
, какой это тип)
Отображение конструкций, специально обработанных компилятором, более или менее следующее:
num == null → !num.HasValue
num != null → num.HasValue
num = null → num = new Nullable<int>()
num = 5 → num = new Nullable<int>(5)
(int) num → num.Value
(object) num → (object) num.Value // if HasValue
→ (object) null // if !HasValue
Существует дополнительная поддержка операторов, наиболее важно операторов сравнения с ненулевыми значениями T
s и различные операторы, которые работают с потенциальными значениями null
, такими как ??
, но в этом суть.