Как оператор сравнения работает с null int?


151

Я начинаю изучать обнуляемые типы и столкнулся со следующим поведением.

При попытке обнулять int, я вижу, оператор сравнения дает мне неожиданный результат. Например, в моем коде ниже, вывод, который я получаю: «оба и 1 равны» . Обратите внимание, что он также не печатает "ноль".

int? a = null;
int? b = 1;

if (a < b)
    Console.WriteLine("{0} is bigger than {1}", b, a);
else if (a > b)
    Console.WriteLine("{0} is bigger than {1}", a, b);
else
    Console.WriteLine("both {0} and {1} are equal", a, b);

Я надеялся, что любое неотрицательное целое число будет больше нуля. Я что-то здесь упускаю?


5
Вот небольшая .NET Fiddle, чтобы увидеть несколько случаев.
Уве Кейм

Ответы:


207

Согласно MSDN - это вниз по странице в разделе «Операторы»:

Когда вы выполняете сравнения с обнуляемыми типами, если значение одного из обнуляемых типов равно, nullа другого нет, все сравнения оцениваются, falseкроме!=

Так что и так a > bи a < bоценивать falseтак aкак ноль ...


2
В своих проектах я в настоящее время использую VB.NET, и кажется, что nothing <> 1= nullв VB, тогда как null != 1= trueв C # - я использовал LinqPad для проверки утверждений
Люк Т О'Брайен,

2
Мне просто интересно, и об этом стоит упомянуть Lifted Operatorsв C # stackoverflow.com/questions/3370110/what-are-lifted-operators - я подумал, может ли это быть причиной того, что VB.NET возвращает разные результаты
Люк Т О'Брайен,

44

Как говорит MSDN

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

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");
}

/* Output:
 * num1 >= num2 returned false (but num1 < num2 also is false)
 * num1 < num2 returned false (but num1 >= num2 also is false)
 * Finally, num1 != num2 returns true!
 * num1 == num2 returns true when the value of each is null
 */

25

Подводя итог: ни в какое сравнение с нулем неравенство ( >=, <, <=, >) возвращает falseдаже если оба операнда равны нулю. т.е.

null >  anyValue //false
null <= null     //false

Любое сравнение на равенство или неравенство с null ( ==, !=) работает «как положено». т.е.

null == null     //true
null != null     //false
null == nonNull  //false
null != nonNull  //true

Это то же самое для обоих int? nonNullи int notNull?
Кое Кто

1
@ КоеКто, такое же поведение для Nullable<NumberTypes> = null. Проверенные.
Артру

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.