Как типы с нулевым значением обрабатывают пустые значения с операторами сравнения?
Кто-нибудь имеет конкретную информацию о том, как С# обрабатывает сравнения с типами 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, когда оно не имеет значения. Таким образом, правила по существу одинаковы. По крайней мере, это то, как я написал свои сравнения. Если я делаю это неправильно, то, святой бог, я делаю это неправильно, и я уверен, что кто-то подскажет мне, как это исправить!