Подтвердить что ты не робот

Почему значение null не равно false?

В чем причина 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...
}
4b9b3361

Ответ 1

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

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

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

Ответ 2

"Я считаю достаточно разумным предположить, что null означает false"

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

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

С приведенным выше я мог бы сделать:

if (instance) {

}

и др.

Ответ 3

"Я считаю достаточно разумным предположить, что null означает false"

Я не согласен. ИМХО, чаще всего, ложно означает "нет". Null означает "я не знаю"; то есть полностью неопределенным.

Ответ 4

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

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

Ответ 5

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

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

Параметры

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

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

Ответ 6

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

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

Ответ 7

Потому что null и false - это разные вещи.

Прекрасным примером является bool? Foo

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

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

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

Ответ 8

В чем причина того, что null не считать false в условных выражениях?

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

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

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

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

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

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

Ответ 9

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

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

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

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

В качестве условного обозначения true - 1, false - 0, а указатель null - либо 0x00, 0x0000, 0x00000000, либо 0x0000000000000000, в зависимости от ширина адресной шины.

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

Это по дизайну.

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

Ответ 10

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

Ответ 11

Это просто система типов С# по сравнению с такими языками, как PHP, Perl и т.д.

Условие принимает только значения Boolean, null не имеет типа Boolean, поэтому он там не работает.

Что касается примера NULL в C/С++, о котором вы упомянули в другом комментарии, то нужно сказать, что ни C, ни С++ не имеют логического типа (afair С++ обычно имеет тип для bool, который разрешает int, но это другое дело), и они также не имеют нулевых ссылок, только NULL (= > 0) -поточников.

Конечно, разработчики компилятора могли бы реализовать автоматическое преобразование для любого типа с нулевым значением в boolean, но это вызовет другие проблемы, то есть:

Предполагая, что foo не null:

if (foo)
{
  // do stuff
}

Какое состояние foo истинно?
Всегда, если это не null?
Но что, если вы хотите, чтобы ваш тип был преобразован в логический (т.е. Из вашего трехгосударственного или квантово-логического класса)?

Это означало бы, что у вас будет два разных преобразования в bool, неявные и явные, которые будут вести себя по-другому.

Я даже не смею представить, что должно произойти, если вы делаете

if (!!foo) // common pattern in C to normalize a value used as boolean,
           // in this case might be abused to create a boolean from an object
{
}

Я думаю, что принудительный (foo == null) хорош, так как он также добавляет ясности в ваш код, он легче понять, что вы действительно проверяете.