Почему null не оценивается как false? - PullRequest
23 голосов
/ 07 июля 2010

По какой причине null не оценивается в false в условных выражениях?

Сначала я подумал о назначениях, чтобы избежать ошибки использования = вместо ==, но это может быть легко запрещено компилятором.

if (someClass = someValue) // cannot convert someClass to bool. Ok, nice

if (someClass) // Cannot convert someClass to bool. Why?

if (someClass != null) // More readable?

Я думаю, что вполне разумно предположить, что null означает false. Есть и другие языки, которые используют это тоже, и у меня не было ошибки из-за этого.

Редактировать: И я, конечно, имею в виду ссылочные типы.

Хороший комментарий Дэниела Эрвикера об ошибке назначения ... Это компилируется без предупреждения, потому что оно оценивается как bool:

bool bool1 = false, bool2 = true;
if (bool1 = bool2)
{
    // oops... false == true, and bool1 became true...
}

Ответы [ 11 ]

23 голосов
/ 07 июля 2010

Это особая конструктивная особенность языка C #: if операторы принимают только bool.

IIRC это для безопасности: особенно, чтобы ваш первый if (someClass = someValue) не может скомпилировать.

Редактировать: Одно преимущество заключается в том, что он делает соглашение if (42 == i) ("сравнение йоды") ненужным.

22 голосов
/ 07 июля 2010

«Я думаю, вполне разумно предположить, что нуль означает ложь»

Не в C #.false - логическая структура, тип значения.Типы значений не могут иметь нулевое значение.Если вы хотите сделать то, что достигли, вам нужно будет создать пользовательские конвертеры вашего конкретного типа в логическое значение:

public class MyClass
{
    public static implicit operator bool(MyClass instance)
    {
        return instance != null;
    }
}

С учетом вышеизложенного я мог бы сделать:* и т.д.

13 голосов
/ 07 июля 2010

«Я думаю, вполне разумно предположить, что нуль означает ложь»

Я не согласенИМХО, чаще всего ложное означает «нет».Нуль означает «я не знаю»;то есть полностью неопределенный.

5 голосов
/ 07 июля 2010

Просто используйте if (Convert.ToBoolean (someClass))

http://msdn.microsoft.com/en-us/library/wh2c31dd.aspx

Параметры

значение Тип: System.Object Объект, который реализует IConvertible интерфейс, или нуль. Возвращаемое значение

Тип: System.Boolean, true или false, который отражает значение, возвращаемое вызывая IConvertible.ToBoolean метод для базового типа значение. Если значение равно нулю, метод возвращает false

5 голосов
/ 07 июля 2010

Одна вещь, которая приходит на ум, как насчет экземпляра типа данных, такого как int? Int не может быть нулевым, поэтому они всегда оценивают как true? Можно предположить, что int = 0 является ложным, но это становится действительно сложным, потому что 0 является допустимым значением (где, возможно, 0 должно принимать значение true, потому что программист установил его), а не просто значением по умолчанию.
Есть много крайних случаев, когда ноль не является опцией, или иногда это опция, а в других случаях это не так.

Они добавляют такие вещи, чтобы защитить программиста от ошибок. Это происходит по той же схеме: почему вы не можете потерпеть неудачу в операторах case.

4 голосов
/ 07 июля 2010

Насколько я знаю, это особенность, которую вы видите в динамических языках, которой нет в C # (согласно спецификации языка if принимает только bool или выражение, которое оценивается как bool).

Я не думаю, что разумно предполагать, что null - это false в в каждом случае. Это имеет смысл в некоторых случаях, но не в других. Например, предположим, что у вас есть флаг, который может иметь три значения: set , unset и un initialized . В этом случае set будет true, unset будет false и не инициализировано будет null. Как видите, в этом случае значение null не равно false.

3 голосов
/ 07 января 2016

Конструктивно большинство людей, которые «не могут придумать ни одной технологической причины, равной нулю, должны быть равны ложному», ошибаются.

Код выполняется процессорами.Большинство (если не все) процессоры имеют биты , группы битов и интерпретации групп битов .Тем не менее, что-то может быть 0, 1, byte, word, dword, qword и т. Д.

Обратите внимание, что на платформе x86 байтыэто октеты (8 бит), а слова обычно 16 бит, но это не обязательно.Старые процессоры имели 4-битные слова, и даже современные встроенные контроллеры низкого уровня часто используют как 7 или 12 бит на слово.

Тем не менее, что-то может быть «равно», «ноль», «больше», «меньше», «больше или равно» или «меньше или равно» в машинном коде.Нет такой вещи как null, false или true.

Как правило, true это 1, false это 0 и указатель nullможет быть 0x00, 0x0000, 0x00000000 или 0x0000000000000000, в зависимости от адресной шины width.

C # является одним из исключений, так как это косвенный типгде два возможных значения 0 и 1 не являются непосредственными значениями, а index структуры (представьте enum в C или PTR в сборке x86).

Это специально.

Важно отметить, однако, что такие проектные решения являются сложными решениями, тогда как традиционный, простой способпредположить, что 0, null и false равны.

3 голосов
/ 07 июля 2010

По какой причине ноль не оценивать как ложное в условных выражениях?

Сначала я подумал о назначении избежать ошибки использования = вместо ==

Это не причина. Мы знаем это, потому что если две сравниваемые переменные имеют тип bool, то код будет скомпилирован довольно счастливо:

bool a = ...
bool b = ...

if (a = b)
    Console.WriteLine("Weird, I expected them to be different");

Если b истинно, сообщение печатается (а a теперь верно, что делает последующий процесс отладки совместимым с сообщением, что еще больше сбивает вас с толку ...)

Причина, по которой null не конвертируется в bool, заключается просто в том, что C # избегает неявного преобразования, если этого не требует разработчик пользовательского типа. Книга истории C ++ полна болезненных историй, вызванных неявными преобразованиями.

3 голосов
/ 07 июля 2010

Потому что нуль и ложь - разные вещи.

Прекрасный пример - bool?foo

Если значение foo равно true, тогда его значение равно true.
Если значение foo равно false, то его значение равно false
Если foo ничего не назначено, его значение равно нулю.

Это три логически отдельных условия.

Подумайте об этом по-другому
" Сколько денег я вам должен? "
" Ничего "и" У меня нет этой информации"- это два совершенно разных ответа.

2 голосов
/ 07 июля 2010

C # не выполняет преобразование параметра, как в C ++.Вам нужно явно преобразовать значение в логическое значение, если вы хотите, чтобы оператор if принял значение.

...