Dlaczego> = zwraca false, gdy = = zwraca true dla wartości null?

Mam dwie zmienne typu int? (lub Nullable jeśli chcesz). Chciałem zrobić większe niż równe (>=) porównanie dwóch zmiennych, ale jak się okazuje, to zwraca false, jeśli obie zmienne są null, podczas gdy oczywiście operator = = zwraca true.

Może mi ktoś wyjaśnić, dlaczego jest to logiczne, ponieważ semantyczna definicja operatora > = zawiera słowo "or"?

Author: Jon, 2010-12-09

8 answers

Była ogromna debata na temat tej dziwności, Kiedy funkcja została pierwotnie zaprojektowana w C# 2.0. Problem polega na tym, że użytkownicy C# są całkowicie przyzwyczajeni do tego, że ma to znaczenie:

if(someReference == null)

Rozszerzając równość na typy wartości nullable, masz następujące opcje.

  1. Zerowa równość jest naprawdę podniesiona. Jeśli jeden lub oba operandy są null, to wynik nie jest ani prawda, ani fałsz, ale null. W takim przypadku możesz albo:

    • A) nielegalne jest posiadanie równości typu nullable value w instrukcji if, ponieważ instrukcja if potrzebuje bool, a nie nullable bool. Zamiast tego Wymagaj, aby wszyscy używali HasValue, jeśli chcą porównać do null. To jest gadatliwe i irytujące.

    • B) automatycznie konwertuje null NA false. Minusem tego jest to, że x==null zwraca false, jeśli x jest null, co jest mylące i działa przeciwko zrozumieniu porównań z null typy referencyjne.

  2. Zerowa równość nie jest zniesiona. Nullable equality is true or false, and comparison to null is a null check. To sprawia, że równość zerowa jest niezgodna z nierównością zerową.

Żaden z tych wyborów nie jest oczywiście poprawny; wszystkie mają plusy i minusy. VBScript wybiera na przykład 1b. Po wielu dyskusjach zespół C # design wybrał #2.

 98
Author: Eric Lippert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-30 15:57:10

Ponieważ Równość jest zdefiniowana oddzielnie od porównywalności.
Możesz przetestować x == null, ale x > null jest bez znaczenia. W C# zawsze będzie false.

 60
Author: Henk Holterman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 15:40:08

Innym sposobem opisania '> = ' jest: nie mniej niż. Nie wspominając o równych sobie. Gdy tylko jeden z operandów w teście bez równości jest Null, wynik jest również Nieznany (jest null). Jeśli jednak chcesz wiedzieć, czy oba operandy są Null, to Null = = Null jest rozsądnym testem (powinno dać wartość true). Pozbycie się części nierówności operatora robi całą różnicę.

Poniższy przykład kodu z http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx#sectionToggle4 podsumowuje jak C# traktuje Null:

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   
 */   
 11
Author: NealB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 17:11:45

>= operuje na wartości liczbowej, której null nie jest.

Możesz przeciążyć operator >=, aby zapewnić to, czego pragniesz na określonym typie.

 2
Author: Aaron McIver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 15:40:35

NULL nie jest zerem (wartością liczbową lub binarną), ciągiem o zerowej długości lub pustym (wartością znakową). Więc każdy operator porównania zawsze zwróci false na nim. Czytaj więcej na ten temat tutaj

 0
Author: Sam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 15:35:01

Jakich wartości można się spodziewać?

Null = = NULL true

Null > = NULL false

Null > NULL false

Null

Null

Null != null false

1 = = null false

1 >= null false

1 > null false

1

1

1 != null true aka !(1 = = null)

 0
Author: Bengie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 17:10:06

> = oznacza tylko "większe lub równe", gdy jest używane w ten konkretny, dobrze zdefiniowany sposób. W przypadku użycia na klasie z przeciążonymi operatorami oznacza to wszystko, co programista klasy chce, aby oznaczało. Gdy zastosowana do klasy podobnej do ciągu, może oznaczać "sortuje to samo lub wyższe" lub może oznaczać "tę samą długość lub dłużej".

 0
Author: Sparr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 23:18:26

Ponieważ domyślnie int nie może być null, a jego wartość zostanie ustawiona na 0, operator > i int, oczekuje pracy z values, a nie z nulls.

Zobacz moją odpowiedź na podobne pytanie, gdzie napisałem kilka sposobów obsługi nullable int za pomocą operatorów less < i greater > https://stackoverflow.com/a/51507612/7003760

 0
Author: Mayer Spitzer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 21:27:42