Как типы с нулевым значением обрабатывают пустые значения с операторами сравнения?

Кто-нибудь имеет конкретную информацию о том, как С# обрабатывает сравнения с типами Nullable<T>, когда одна сторона сравнения имеет значение null?

Как я понимаю из экспериментов с компилятором, кажется, что сравнение всегда возвращает false, но я не могу найти документацию, подтверждающую это. Является ли это реальной особенностью языка (и, следовательно, что-то, на что я могу рассчитывать), или это детали реализации, которые могут измениться в будущих версиях?

Другими словами, возвращает ли следующий метод true значение y.HasValue, и можете ли вы указать мне какую-нибудь документацию, подтверждающую, что это происходит?

    public bool foo(int x, int? y)
    {
        return x < y;
    }

Ответ 1

Кто-нибудь имеет конкретную информацию о том, как С# обрабатывает сравнения с типами Nullable, когда одна сторона сравнения равна null?

Да - спецификация языка С#, раздел 7.3.7. В этом случае он является реляционным оператором:

Для операторов отношений < > <= >= существует поднятая форма оператора, если типы операндов являются неинифицируемыми типами и если тип результата равен bool. Поднятая форма строится путем добавления единственного модификатора ? к каждому типу операнда. Поднятый оператор выдает значение false, если один или оба операнда равны нулю. В противном случае, снятый оператор разворачивает операнды и применяет основной оператор для получения результата bool.

Аналогичные подробные разделы для других операторов.

Если вы сомневаетесь в том, как работает какой-либо аспект языка (и гарантирован ли он или специфичен для конкретной реализации), спецификация языка С# должна быть вашим первым портом захода.

Ответ 2

Если одно из значений равно null, сравнение будет ложным (кроме !=)

Когда вы выполняете сравнения с типами NULL, если значение одного нулевых типов - null, а другой - нет, все сравнения оценивать значение false, за исключением if = (не равно). Важно не предположим, что, поскольку конкретное сравнение возвращает false, противоположный случай возвращает true. В следующем примере 10 не больше, меньше или равно нулю. Только num1!= Num2 имеет значение true.

Источник MSDN

Ответ 3

В MSDN есть следующее:

Когда вы выполняете сравнения с типами NULL, если значение одного из нулевых типов является нулевым, а другое - нет, все сравнения оцениваются как false, за исключением: = (не равно).

http://msdn.microsoft.com/en-us/library/2cf62fcy(v=vs.100).aspx

Вот приведенные примеры кода:

int? num1 = 10;
int? num2 = null;
if (num1 >= num2)
{
    Console.WriteLine("num1 is greater than or equal to num2");
}
else
{
    // This clause is selected, but num1 is not less than num2.
    Console.WriteLine("num1 >= num2 returned false (but num1 < num2 also is false)");
}

if (num1 < num2)
{
    Console.WriteLine("num1 is less than num2");
}
else
{
    // The else clause is selected again, but num1 is not greater than
    // or equal to num2.
    Console.WriteLine("num1 < num2 returned false (but num1 >= num2 also is false)");
}
if (num1 != num2)
{
    // This comparison is true, num1 and num2 are not equal.
    Console.WriteLine("Finally, num1 != num2 returns true!");
}
// Change the value of num1, so that both num1 and num2 are null.
num1 = null;
if (num1 == num2)
{
    // The equality comparison returns true when both operands are null.
    Console.WriteLine("num1 == num2 returns true when the value of each is null");
}

Ответ 4

Если не реализовано определенное CompareTo, то мое исследование подсказывает мне, что объект будет использовать CompareTo (object). В случае с int вы можете сравнить с int или объектом. В этом случае он проверяет только, является ли объект нулевым или нет. Здесь ссылка на int CompareTo (объект), она детализирует причину результатов сравнения int и объекта.

http://msdn.microsoft.com/en-us/library/system.int32.aspx

Я не могу найти ничего точно, но я не вижу ничего, что указывает на то, что платформа .NET была расширена, чтобы включить метод CompareTo для System.Nullable<T> для каждого <T>.

Если бы это был мой код, я бы защитил себя и расширил класс Int, включив CompareTo.

Ответ 5

Я знаю, что опаздываю, но я брошу свои два цента.

Если используется память, правила для сравнения следующие:

  • Если x и y равны нулю, верните 0 (они равны).
  • Если x равно null, а y - нет, return -1 (x меньше y).
  • Если x не является нулевым, а y равно null, return 1 (x больше y).

Для всех непустых значений:

  • Когда значение x оценивается меньше y, возвращаем -1.
  • Когда значение x вычисляет y, верните 0.
  • Когда значение x будет больше, чем y, верните 1.

Для всех целей и целей, Nullable <T> оценивает значение null, когда оно не имеет значения. Таким образом, правила по существу одинаковы. По крайней мере, это то, как я написал свои сравнения. Если я делаю это неправильно, то, святой бог, я делаю это неправильно, и я уверен, что кто-то подскажет мне, как это исправить!