¿Cómo funciona el operador de comparación con null int?

151

Estoy empezando a aprender tipos anulables y me encontré con el siguiente comportamiento.

Al intentar int nullable, veo que el operador de comparación me da un resultado inesperado. Por ejemplo, en mi código a continuación, el resultado que obtengo es "ambos y 1 son iguales" . Tenga en cuenta que tampoco 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);

Esperaba que cualquier número entero no negativo fuera mayor que nulo, ¿me estoy perdiendo algo aquí?

Ron5504
fuente
55
Aquí hay un pequeño .NET Fiddle para ver varios casos.
Uwe Keim

Respuestas:

207

Según MSDN , está en la página de la sección "Operadores":

Cuando realiza comparaciones con tipos anulables, si el valor de uno de los tipos anulables es nully el otro no, todas las comparaciones se evalúan falseexcepto!=

Entonces ambos a > by a < bevaluar falsecomo aes nulo ...

nkvu
fuente
2
En mis proyectos actualmente estoy usando VB.NET y parece que nothing <> 1= nullen VB mientras que null != 1= trueen C # --He estado usando LinqPad para probar las declaraciones
Luke T O'Brien
2
Simplemente me preguntaba, y vale la pena mencionarlo Lifted Operatorsen C # stackoverflow.com/questions/3370110/what-are-lifted-operators - Me preguntaba si esta podría ser la razón por la que VB.NET devuelve resultados diferentes
Luke T O'Brien
44

Como dice MSDN

Cuando realiza comparaciones con tipos anulables, si el valor de uno de los tipos anulables es nulo y el otro no, todas las comparaciones se evalúan como falsas, excepto para! = (No es igual). Es importante no asumir que debido a que una comparación particular devuelve falso, el caso opuesto devuelve verdadero. En el siguiente ejemplo, 10 no es mayor que, menor que, ni igual a nulo. Solo num1! = Num2 se evalúa como verdadero.

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
fuente
25

Para resumir: cualquier comparación con la desigualdad nulo ( >=, <, <=, >) devuelve falseincluso si ambos operandos son nulos. es decir

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

Cualquier comparación de igualdad o no igualdad con nulo ( ==, !=) funciona 'como se esperaba'. es decir

null == null     //true
null != null     //false
null == nonNull  //false
null != nonNull  //true
GDS
fuente
¿Es lo mismo para ambos int? nonNully int notNull?
Кое Кто
1
@ КоеКто, el mismo comportamiento es para Nullable<NumberTypes> = null. Verificado
Artru
2

Comparar C # con SQL

C #: a = nulo y b = nulo => a == b => verdadero

SQL: a = nulo y b = nulo => a == b => falso

Gunnar Siréus
fuente