Почему пустой указатель не оценивает ко лжи?

Вот почему они удаляют это использование переменных. Из руководства :

Порядок вычисления выражений с участием пользовательских переменных не определен. Например, нет гарантии, что SELECT @a, @a:=@a+1 сначала вычислит @a, а затем выполнит присваивание.

blockquote>

Нет никакой гарантии относительно порядка выполнения назначений переменных в вашем SELECT, так что, как представляется, происходит во втором запросе, что @date_diff вычисляется до [ 117] значение @date_to обновляется. Самый простой способ обойти это - удалить переменные:

SELECT 
    FIRST_VALUE(DATE(`date_time`)) OVER (ORDER BY `date_time`) AS `Date From`,
    LAST_VALUE(DATE(`date_time`)) OVER (ORDER BY `date_time` ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS `Date To`,
    TIMESTAMPDIFF(DAY, FIRST_VALUE(DATE(`date_time`)) OVER (ORDER BY `date_time`), LAST_VALUE(DATE(`date_time`)) OVER (ORDER BY `date_time` ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)) AS `Period [D]`
FROM test
WHERE `date_time` BETWEEN '2017-01-02' AND '2017-01-12'            
LIMIT 1

Или использовать подзапрос, чтобы сделать его более аккуратным:

SELECT `Date From`, `Date To`, TIMESTAMPDIFF(DAY, `Date From`, `Date To`) AS `Period [D]`
FROM (SELECT 
        FIRST_VALUE(DATE(`date_time`)) OVER (ORDER BY `date_time`) AS `Date From`,
        LAST_VALUE(DATE(`date_time`)) OVER (ORDER BY `date_time` ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS `Date To`
      FROM test
      WHERE `date_time` BETWEEN '2017-01-02' AND '2017-01-12'            
      LIMIT 1) t

23
задан Dawid Ferenczy Rogožan 17 March 2016 в 19:44
поделиться

11 ответов

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

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

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

23
ответ дан 29 November 2019 в 00:44
поделиться

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

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

14
ответ дан 29 November 2019 в 00:44
поделиться

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

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

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

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

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

3
ответ дан 29 November 2019 в 00:44
поделиться

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

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

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

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

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

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

Это по замыслу.

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

3
ответ дан 29 November 2019 в 00:44
поделиться

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

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

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

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

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

if (foo)
{
  // do stuff
}

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

Это будет означать, что у вас будет два разных преобразования в 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) хорош, поскольку он также добавляет ясности вашему коду, легче понять, что вы делаете. действительно проверьте.

1
ответ дан 29 November 2019 в 00:44
поделиться

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

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

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

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

if (instance) {

}

и т.д.

22
ответ дан 29 November 2019 в 00:44
поделиться

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

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

5
ответ дан 29 November 2019 в 00:44
поделиться

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

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

Параметры

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

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

5
ответ дан 29 November 2019 в 00:44
поделиться

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

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

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

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

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

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

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

3
ответ дан 29 November 2019 в 00:44
поделиться

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

2
ответ дан 29 November 2019 в 00:44
поделиться

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

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

4
ответ дан 29 November 2019 в 00:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: