Подтвердить что ты не робот

Почему свойство Nullable <T> HasValue не выбрасывает исключение NullReferenceException в Nulls?

Рассмотрим следующий код:

DateTime? ndate = null;
Console.WriteLine(ndate.HasValue);

Я бы ожидал исключение NullReferenceException, но HasValue действительно вернет false. Однако, поскольку ndate имеет значение null, как происходит вызов свойства, поскольку нет объекта для вызова свойства HasValue?

4b9b3361

Ответ 1

Технически "ndate" не является нулевым - это тип значения, при этом значение указано как null.

Когда вы пишете DateTime?, это просто сокращение для Nullable<DateTime>, которое является структурой. Для этого нет никакого способа, чтобы технически было null, так как это не ссылочный тип.

Ответ 2

Nullable<T> - это структура, в основном она не может содержать значение null.

Ваше назначение, фактически скомпилировано во что-то, что выглядит так:

Nullable<DateTime> ndate = new Nullable<DateTime>();

В другом примере выражение:

int? a = null;

Будет сгенерирован следующий IL:

.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0)
IL_0000:  ldloca.s   V_0
IL_0002:  initobj    valuetype [mscorlib]System.Nullable`1<int32>

Вызов операции initobj, которая инициализирует каждое поле типа значения по указанному адресу нулевой ссылке или 0 соответствующего примитивного типа.

В заключение, то, что здесь происходит, является инициализацией структуры .

Ответ 3

Я бы ожидал исключение NullReferenceException

Нет нулевой ссылки, которая разыменовывается, поэтому "NullReferenceException" не следует ожидать. Нулевая дата DateTime не является нулевой ссылкой. Это нулевое значение.

Однако, поскольку ndate имеет значение null, как выполняется вызов свойства, поскольку нет объекта для вызова свойства HasValue?

Вопрос предполагает ложную предпосылку. Есть объект. Существует нулевое значение DateTime, представляющее нулевое значение nullableTimeTime. Это значение является объектом.

Рассмотрите свой код:

DateTime? ndate = null; 
Console.WriteLine(ndate.HasValue); 

Это всего лишь короткий способ написать то, что логически похоже:

DateTime ndate = default(DateTime); 
bool ndateHasValue = false;
Console.WriteLine(ndateHasValue); 

Тип с нулевым значением - просто приятный способ написать код, который означает "пожалуйста, приложите булеву к этой вещи, которая отслеживает, является ли она логически нулевой или нет".

Ответ 4

Что действительно происходит, так что фактическая (не нулевая) структура Nullable присваивается переменной, поэтому переменная не равна нулю, но это значение.

Ответ 5

Синтаксический сахар мой друг... компилятор превращает этот .HasValue в код, который не будет генерировать исключение: -)