Як працює оператор порівняння з null int?


151

Я починаю вивчати мінливі типи і натрапив на наступну поведінку.

Під час спроби зворотного int, я бачу, що оператор порівняння дає мені несподіваний результат. Наприклад, у моєму коді нижче: Вихід, який я отримую, - "і обидва, і 1 рівні" . Зауважте, він також не друкує "null".

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, щоб побачити кілька випадків.
Uwe Keim

Відповіді:


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 повертає різні результати
Luke T O'Brien

44

Як каже MSDN

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

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. Перевірено.
Artru

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.