Como o operador de comparação trabalha com int nulo?

151

Estou começando a aprender tipos anuláveis ​​e tive o seguinte comportamento.

Ao tentar int nulo, vejo operador de comparação me dá resultado inesperado. Por exemplo, no meu código abaixo, a saída que recebo é "ambos e 1 são iguais" . Observe que ele também não imprime "nulo".

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

Eu esperava que qualquer número inteiro não negativo fosse maior que nulo. Estou perdendo alguma coisa aqui?

Ron5504
fonte
5
Aqui está um pequeno .NET Fiddle para ver vários casos.
Uwe Keim

Respostas:

207

De acordo com o MSDN - está abaixo da página na seção "Operadores":

Quando você executa comparações com tipos anuláveis, se o valor de um dos tipos anuláveis ​​é nulle o outro não, todas as comparações são avaliadas como falseexceto!=

Então, tanto a > be a < bavaliar como falsedesde aé nulo ...

nkvu
fonte
2
Em meus projetos Atualmente, estou usando VB.NET e parece que nothing <> 1= nullem VB enquanto null != 1= trueem C # - Eu tenho usado LinqPad para testar as declarações
Luke T O'Brien
2
Eu apenas me perguntei, e vale a pena notar Lifted Operatorsem C # stackoverflow.com/questions/3370110/what-are-lifted-operators - imaginei se esse seria o motivo pelo qual o VB.NET retornaria resultados diferentes
Luke T. O'Brien
44

Como o MSDN diz

Quando você executa comparações com tipos anuláveis, se o valor de um dos tipos anuláveis ​​for nulo e o outro não, todas as comparações serão avaliadas como falsas, exceto! = (Não é igual). É importante não supor que, como uma comparação específica retorne falsa, o caso oposto retorne verdadeiro. No exemplo a seguir, 10 não é maior que, menor que nem igual a nulo. Somente num1! = Num2 é avaliado como verdadeiro.

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
 */
Parimal Raj
fonte
25

Para resumir: qualquer comparação de desigualdade com nula ( >=, <, <=, >) retorna falsemesmo se ambos os operandos são nulos. ie

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

Qualquer comparação de igualdade ou não-igualdade com null ( ==, !=) funciona 'conforme o esperado'. ie

null == null     //true
null != null     //false
null == nonNull  //false
null != nonNull  //true
GDS
fonte
É o mesmo para ambos int? nonNulle int notNull?
Кое Кто
1
@ КоеКто, O mesmo comportamento é para Nullable<NumberTypes> = null. Verificado.
Artru 11/02/19
2

Comparando C # com SQL

C #: a = nulo eb = nulo => a == b => verdadeiro

SQL: a = nulo eb = nulo => a == b => false

Gunnar Siréus
fonte