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

Почему мне разрешено сравнивать тип с нулевым значением с нулем?

Возможный дубликат:
С# в порядке со сравнением типов значений с нулем

Если я попытаюсь назначить null нечетному типу в С#:

System.DateTime time = null;

Я получу ошибку времени компиляции:

error CS0037: Невозможно преобразовать значение null в 'System.DateTime', потому что это тип с нулевым значением

что имеет смысл. Но если сравнивать один и тот же тип с null:

System.DateTime time = obtainFromSomewhere();
if( time == null ) {
    //whatever;
}

нет ошибки времени компиляции. Для меня это не имеет смысла - если я не могу назначить null, то зачем ему когда-либо быть null?

Почему мне разрешено сравнивать тип с нулевым значением с null?

4b9b3361

Ответ 1

Причина, по которой это работает для DateTime, заключается в том, что DateTime определяет ее собственный оператор ==. Поскольку он делает это, он получает отмененную версию оператора, которая может использоваться с DateTime?. Поскольку DateTime и null могут быть неявно преобразованы в DateTime?, сравнение компилируется, но всегда будет оцениваться как false во время выполнения.

Спасибо Мэтту Эллен за то, что мой первоначальный ответ не охватывал пример в вопросе.

Ответ 2

Из-за Бокс.

DateTime может быть помечен как object и, таким образом, он становится ссылкой, которую можно сравнить с null (хотя она всегда будет false).

Однако объект (null) не может быть снова распакован на DateTime, поэтому его нельзя назначить DateTime.

Пример: вы могли бы сделать

object now = DateTime.Now;
bool isNull = now == null

EDIT: Как отметил Брайан Расмуссен, я ошибался в теории бокса. Бокс будет происходить только в том случае, если он явно подвергнут объекту, как в моем примере, или в (object)DateTime.Now == null.

Ответ 3

Существует неявное преобразование в нулевой тип с .NET 2.0 (см., что сказал Эрик Липперт здесь).

Компилятор выдает следующее предупреждение, указывающее на то, что происходит преобразование:

C:\>c:\windows\Microsoft.NET\Framework\v2.0.50727\csc test.cs
Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.4927
for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727

test.cs(16,12): warning CS0464: Comparing with null of type 'int?' always produces 'false'

В .NET 1.1, который не имеет типов с нулевым значением, ваш образец кода не был бы законным:

C:\>c:\windows\Microsoft.NET\Framework\v1.1.4322\csc test.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.3052.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.

test.cs(12,13): error CS0019: Operator '==' cannot be applied to operands of type 'System.DateTime' and ''

Ответ 4

он должен быть нулевым типом:

System.DateTime? time = null;

ваш код должен выглядеть следующим образом:

System.DateTime? time = obtainFromSomewhere();
if( time.HasValue ) {
    //use time.Value;
}

но помните, что ваша функция obtainFromSomewhere должна возвращать тип DateTime?.

Ответ 5

По-моему, это разрешено, потому что NULL не является реальным значением из-за отсутствия типа.

Хорошо, что допустим некоторый код, как показано ниже:

System.DateTime time = obtainFromSomewhere(); // allways a date
System.DateTime? otherTime = obtainFromSomewhereElse(); // null if nothing planned

if (time == otherTime)
{
    // match
    ...
}

Что бы мы сделали без нулевого в любом случае?