У меня есть две переменные типа int? (или Nullable <int> если вы это сделаете). Я хотел бы сделать сравнение ( > =) по сравнению с двумя переменными, но, как оказалось, это возвращает false, если обе переменные равны нулю, а, очевидно, оператор == возвращает true.
Может кто-нибудь объяснить мне, почему это логично, потому что семантическое определение операторa >= содержит слово "или"?
Произошла огромная дискуссия об этой странности, когда функция была первоначально разработана в С# 2.0. Проблема в том, что пользователи С# полностью используют это значение:
if(someReference == null)
При расширении равенства к типам значений с нулевым значением у вас есть следующие варианты.
Неудачное равенство действительно отменено. Если один или оба операнда равны нулю, то результат не является ни истинным, ни ложным, но значением null. В этом случае вы можете:
a) Сделать недопустимым использование равенства типа nullable в выражении if
, потому что для оператора if
требуется bool, а не nullable bool. Вместо этого попросите всех использовать HasValue
, если они хотят сравнить с нулем. Это многословно и раздражает.
b) Автоматически конвертировать значение null в значение false. Недостатком этого является то, что x==null
возвращает false, если x равно null, что запутывает и работает против понимания людьми нулевых сравнений со ссылочными типами.
Невозможное равенство не снимается. Неверное равенство является либо истинным, либо ложным, а сравнение с null - это нулевая проверка. Это делает недействительным равенство несовместимым с нулевым неравенством.
Ни один из этих вариантов явно не прав; все они имеют за и против. Например, VBScript выбирает 1b. После долгих дебатов команда разработчиков С# выбрала № 2.
Поскольку равенство определяется отдельно от сопоставимости.
Вы можете протестировать x == null
, но x > null
не имеет смысла. В С# он всегда будет ложным.
Другим способом описания " > =" является: Не меньше, чем. Никаких упоминаний о равных. Как только один из операндов в тесте без равенства равен Null, результат также неизвестен (равен null). Однако, если вы хотите знать, являются ли оба операнда Null, то Null == Null - разумный тест (должен привести к истине). Избавление от части неравенства оператора делает разницу.
Следующий пример кода из http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx#sectionToggle4 показывает, как С# обрабатывает 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
*/
Null == x
которое является явным тестом для unknown, приводя либо к true, либо к false.
>=
работает с числовым значением; который null не является.
Вы можете перегрузить оператор >=
, чтобы обеспечить то, что вы хотите по определенному типу.
>= означает только "больше или равно" при использовании в этом конкретном четко определенном виде. При использовании в классе с перегруженными операторами это означает все, что хочет сказать разработчик класса. При применении к строкоподобному классу это может означать, что "сортируется одинаково или выше", или может означать "ту же длину или дольше".
Какие значения вы ожидаете?
null == null true
null >= null false
null > null false
null <= null false
null < null false
null!= null false
1 == null false
1 >= null false
1 > null false
1 <= null false
1 < null false
1!= null true aka! (1 == null)
NULL не равен нулю (числовое или двоичное значение), строка нулевой длины или пустое (значение символа). Поэтому любой оператор сравнения всегда будет возвращать false. Подробнее об этом читайте здесь
null
. Кроме того, операторы сравнения в C # обнуляемых типах - странный зверь, который не обязательно следует обычным правилам для нулевых сравнений.