Dlaczego> = zwraca false, gdy = = zwraca true dla wartości null?
Mam dwie zmienne typu int? (lub Nullable
Może mi ktoś wyjaśnić, dlaczego jest to logiczne, ponieważ semantyczna definicja operatora > = zawiera słowo "or"?
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.
-
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ż instrukcjaif
potrzebuje bool, a nie nullable bool. Zamiast tego Wymagaj, aby wszyscy używaliHasValue
, 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.
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.
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.
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
*/
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.
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
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)
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".
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
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