Comment fonctionne l'opérateur de comparaison avec null int?

151

Je commence à apprendre les types Nullable et j'ai rencontré le comportement suivant.

En essayant de nullable int, je vois que l'opérateur de comparaison me donne un résultat inattendu. Par exemple, dans mon code ci-dessous, la sortie que j'obtiens est "les deux et 1 sont égaux" . Notez qu'il n'imprime pas non plus "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);

J'espérais que tout entier non négatif serait supérieur à null, est-ce que je manque quelque chose ici?

Ron5504
la source
5
Voici un petit violon .NET pour voir plusieurs cas.
Uwe Keim

Réponses:

207

Selon MSDN - c'est en bas de la page dans la section "Opérateurs":

Lorsque vous effectuez des comparaisons avec des types Nullable, si la valeur de l'un des types Nullable est nullet que l'autre ne l'est pas, toutes les comparaisons sont évaluées à l' falseexception de!=

Donc, les deux a > bet a < bévaluer falsedepuis aest nul ...

nkvu
la source
2
Dans mes projets, j'utilise actuellement VB.NET et il semble que nothing <> 1= nullen VB alors que null != 1= trueen C # - J'utilise LinqPad pour tester les déclarations
Luke T O'Brien
2
Je me suis juste demandé, et cela vaut la peine de le noter Lifted Operatorsdans C # stackoverflow.com/questions/3370110/what-are-lifted-operators - je me suis demandé si cela pourrait être la raison pour laquelle VB.NET renvoie des résultats différents
Luke T O'Brien
44

Comme le dit MSDN

Lorsque vous effectuez des comparaisons avec des types Nullable, si la valeur de l'un des types Nullable est NULL et que l'autre ne l'est pas, toutes les comparaisons ont la valeur false sauf pour! = (Différent de). Il est important de ne pas supposer que, comme une comparaison particulière renvoie faux, le cas contraire renvoie vrai. Dans l'exemple suivant, 10 n'est ni supérieur, ni inférieur, ni égal à null. Seul num1! = Num2 est évalué à vrai.

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
la source
25

Pour résumer: toute comparaison avec l'inégalité nulle ( >=, <, <=, >) retourne falsemême si les deux opérandes sont nuls. c'est à dire

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

Toute comparaison d'égalité ou de non-égalité avec null ( ==, !=) fonctionne «comme prévu». c'est à dire

null == null     //true
null != null     //false
null == nonNull  //false
null != nonNull  //true
GDS
la source
Est-ce la même chose pour les deux int? nonNullet int notNull?
Кое Кто
1
@ КоеКто, Le même comportement est pour Nullable<NumberTypes> = null. Vérifié.
Artru
2

Comparaison de C # avec SQL

C #: a = null et b = null => a == b => vrai

SQL: a = null et b = null => a == b => faux

Gunnar Siréus
la source