Должен ли я использовать `! IsGood` или` IsGood == false`?

Я вижу код, который выполняет такие проверки

if (IsGood == false)
{
   DoSomething();
}

или

if (IsGood == true)
{
   DoSomething();
}

Я ненавижу этот синтаксис и всегда использую следующий синтаксис.

if (IsGood)
{
   DoSomething();
}

или

if (!IsGood)
{
   DoSomething();
}

Есть ли причина использовать '== true' или '== false'?

Это читаемость? Неужели люди просто не понимают логические переменные?

Кроме того, есть ли разница в производительности между двумя?

Ответ 1

Я следую тому же синтаксису, что и вы, он менее подробный.

Люди (более начинающие) предпочитают использовать == true, чтобы быть уверенными в том, чего они хотят. Они используются для использования оператора в их условном... они считают его более читаемым. Но как только вы стали более продвинутыми, вы обнаружили, что это раздражает, потому что оно слишком многословное.

Ответ 2

Я всегда хихикаю (или бросаю что-то у кого-то, в зависимости от моего настроения), когда я сталкиваюсь

if (someBoolean == true) { /* ... */ }

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

if ((someBoolean == true) == true) { /* ... */ }

но, конечно, это действительно должно быть

if (((someBoolean == true) == true) == true) { /* ... */ }

но, конечно...

(ah, компиляция не удалась. Вернуться к работе.)

Ответ 3

Я бы предпочел вариант более короткий. Но иногда == false помогает сделать код еще короче:

Для реального сценария в проектах с использованием С# 2.0 я вижу только одну вескую причину: bool? type. Трехзначное значение bool? полезно, и поэтому легко проверить одно из его возможных значений.

На самом деле вы не можете использовать (!IsGood), если IsGood - bool?. Но запись (IsGood.HasValue && IsGood.Value) хуже, чем (IsGood == true).

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

    bool? value = true; // try false and null too

    if (value == true)
    {
        Console.WriteLine("value is true");
    }
    else if (value == false)
    {
        Console.WriteLine("value is false");
    }
    else
    {
        Console.WriteLine("value is null");
    }

Есть еще один случай, который я только что обнаружил, где if (!IsGood) { ... } не совпадает с if (IsGood == false) { ... }. Но это нереалистично;) Перегрузка операторов может здесь помочь:) (и оператор true/false, что AFAIK не рекомендуется в С# 2.0, потому что целью является предоставление поведения типа bool для пользовательского типа и теперь вы можете получить его со стандартным типом!)

using System;

namespace BoolHack
{
    class Program
    {
        public struct CrazyBool
        {
            private readonly bool value;

            public CrazyBool(bool value)
            {
                this.value = value;
            }

            // Just to make nice init possible ;)
            public static implicit operator CrazyBool(bool value)
            {
                return new CrazyBool(value);
            }

            public static bool operator==(CrazyBool crazyBool, bool value)
            {
                return crazyBool.value == value;
            }

            public static bool operator!=(CrazyBool crazyBool, bool value)
            {
                return crazyBool.value != value;
            }

            #region Twisted logic!

            public static bool operator true(CrazyBool crazyBool)
            {
                return !crazyBool.value;
            }

            public static bool operator false(CrazyBool crazyBool)
            {
                return crazyBool.value;
            }

            #endregion Twisted logic!
        }

        static void Main()
        {
            CrazyBool IsGood = false;

            if (IsGood)
            {
                if (IsGood == false)
                {
                    Console.WriteLine("Now you should understand why those type is called CrazyBool!");
                }
            }
        }
    }
}

Итак... пожалуйста, используйте операторную перегрузку с осторожностью: (

Ответ 4

Согласно Code Complete книга Джефф получил свое имя от и с большим уважением относится к тому, как вы должны лечить булевы.

if (IsGood)
if (!IsGood)

Я использую, чтобы фактически сравнивать логические значения, но я решил, что добавляет дополнительный шаг к процессу и обрабатывает булевы как второстепенные типы. По моему мнению, сравнение возвращает логическое значение, а булевский тип уже является логическим, поэтому почему бы просто не использовать логическое значение.

На самом деле дебаты сводятся к использованию хороших имен для ваших логических объектов. Как вы делали выше, я всегда формулирую свои логические объекты в вопросе. Например,

  • IsGood
  • HasValue
  • и др.

Ответ 5

Метод тестирования специфически против true или false определенно является плохой практикой, если рассматриваемая переменная действительно должна использоваться как логическое значение (даже если его тип не является логическим), особенно в C/С++. Тестирование против true может (и, вероятно, будет) приводить к тонким ошибкам:

Эти, по-видимому, аналогичные тесты дают противоположные результаты:

// needs C++ to get true/false keywords
// or needs macros (or something) defining true/false appropriately
int main( int argc, char* argv[])
{
    int isGood = -1;

    if (isGood == true) {
        printf( "isGood == true\n");
    }
    else {
        printf( "isGood != true\n");
    }

    if (isGood) {
        printf( "isGood is true\n");
    }
    else {
        printf( "isGood is not true\n");
    }

    return 0;
}

Отобразится следующий результат:

isGood != true
isGood is true

Если вы чувствуете необходимость тестировать переменную, которая используется в качестве логического флага против true/false (что не должно быть сделано по моему мнению), вы должны использовать идиому, всегда проверяющую ложь, потому что false может иметь только один value (0), в то время как истина может иметь несколько возможных значений (ничего, кроме 0):

if (isGood != false) ...  // instead of using if (isGood == true)

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

См. этот вопрос SO для примера того, где эта проблема на самом деле забила кого-то...

Ответ 6

Я согласен с вами (и меня тоже это раздражает). Я думаю, что это просто небольшое недоразумение, которое IsGood == true оценивает как bool, с чего начинался IsGood.

Я часто вижу эти близкие экземпляры SomeStringObject.ToString().

Тем не менее, на языках, которые проигрывают с типами, это может быть оправдано. Но не в С#.

Ответ 7

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

if(IsGood) DoSomething();

или

if(IsBad == false) DoSomething();

вместо

if(!IsBad) DoSomething();

Но опять же, это не имеет большого значения для меня, и я уверен, что он заканчивается тем же ИЛ.

Ответ 8

Только для чтения.

Если что-то, что вы предпочитаете, более эффективно при компиляции в машинный код. Однако я ожидаю, что они будут производить точно тот же машинный код.

Ответ 9

Из ответов до сих пор это, кажется, консенсус:

  • В большинстве случаев краткая форма является лучшей. (IsGood и! IsGood)
  • Булевы переменные должны быть записаны как положительные. (IsGood вместо IsBad)
  • Так как большинство компиляторов выдает один и тот же код в любом случае, разница в производительности отсутствует, за исключением случаев интерпретируемых языков.
  • Эта проблема не имеет явного победителя, вероятно, можно рассматривать как битву в религиозной войне стиля кодирования.

Ответ 10

Я предпочитаю использовать:

if (IsGood)
{
    DoSomething();
}

и

if (IsGood == false)
{
    DoSomething();
}

поскольку я считаю, что это более читаемо -! просто слишком легко пропустить (как при чтении, так и при печати); также "если не IsGood then..." просто не звучит правильно, когда я его слышу, в отличие от "if IsGood is false then...", который звучит лучше.

Ответ 11

Возможно (хотя и маловероятно, по крайней мере, я надеюсь), что в C-коде TRUE и FALSE # определены для вещей, отличных от 1 и 0. Например, программист, возможно, решил использовать 0 как "истинный" и -1 как "false" в конкретном API. То же самое относится к устаревшему коду С++, поскольку "true" и "false" не всегда были ключевыми словами С++, особенно за день до того, как появился стандарт ANSI.

Также стоит отметить, что некоторые языки, в частности, script -y, такие как Perl, JavaScript и PHP, могут иметь смешные интерпретации значений, которые считаются истинными, а какие значения считаются ложными. Возможно (хотя, опять же, маловероятно, надеждах), что "foo == false" означает нечто тонкое, отличное от "! Foo". Этот вопрос помечен как "языковой агностик", а язык может определять оператор ==, чтобы он не работал способами, совместимыми с! Оператор.

Ответ 12

Я видел следующее как требование стиля C/С++.

if ( true == FunctionCall()) {
  // stuff
}

Причиной было то, что вы случайно положили "=" вместо "==", компилятор заработает при назначении значения константе. Тем временем это вредит читабельности каждого отдельного оператора if.

Ответ 13

Иногда он используется с точки зрения удобочитаемости. Иногда именованный вызов переменной или функции может оказаться двойным отрицательным, что может сбивать с толку, и сделать ожидаемый тест таким же, как это, может помочь в удобочитаемости.

Хорошим примером этого может быть strcmp() C/С++, который возвращает 0, если строки равны, в противном случае < или > 0, в зависимости от того, где разница. Поэтому вы часто увидите:

if(strcmp(string1, string2)==0) { /*do something*/ }

Как бы то ни было, я согласен с вами, что

if(!isCached)
{
    Cache(thing);
}

понятнее читать.

Ответ 14

Я предпочитаю! IsGood, потому что для меня это более ясно и понятно. Проверка того, является ли логическое value == true избыточным, поэтому я бы этого избежал. Синтаксически, хотя, я не думаю, что есть разница, если IsGood == false.

Ответ 15

Я предпочитаю подход IsGood, и я думаю, что большинство людей, пришедших с языкового фона в стиле c, тоже предпочтут его. Я только угадываю здесь, но я думаю, что большинство людей, которые пишут IsGood == False, взяты из более подробного языкового фона, такого как Visual Basic.

Ответ 16

Для удобства чтения вы можете рассмотреть свойство, основанное на другом свойстве:

public bool IsBad get { { return !IsGood; } }

Тогда вы действительно можете понять смысл:

if(IsBad)
{
    ...
}

Ответ 17

Шаблон !IsGood - это eaiser, чтобы найти, чем IsGood == false, когда он сведен к регулярному выражению.

/\b!IsGood\b/

против

/\bIsGood\s*==\s*false\b/
/\bIsGood\s*!=\s*true\b/
/\bIsGood\s*(?:==\s*false|!=\s*true)\b/

Ответ 18

Лично я предпочитаю форму, о которой говорит дядя Боб в "Чистом коде":

(...)
    if (ShoouldDoSomething())
    {
        DoSomething();
    }
(...)

bool ShouldDoSomething()
{
    return IsGood;
}

где условности, кроме самых тривиальных, помещаются в предикатные функции. Тогда не имеет значения, насколько читабельна реализация булевского выражения.

Ответ 19

Во многих языках разница заключается в том, что в одном случае у вас есть компилятор/интерпретатор, диктующий значение true или false, в то время как в другом случае он определяется кодом. C является хорошим примером этого.

if (something) ...

В приведенном выше примере "что-то" сравнивается с определением компилятора "true". Обычно это означает "не ноль".

if (something == true) ...

В приведенном выше примере "что-то" сравнивается с "истинным". И тип "истина" (и, следовательно, сопоставимость), и значение "истина" могут или не могут быть определены языком и/или компилятором/интерпретатором.

Часто два не совпадают.

Ответ 20

Единственное, что хуже -

if (true == IsGood) {....

Никогда не понимал мысль, стоящую за этим методом.

Ответ 21

Вы забыли:

if (IsGood == FileNotFound)

Ответ 22

Мне кажется (хотя у меня нет доказательств, подтверждающих это), что люди, которые начинают на языках С#/java, предпочитают метод if (CheckSomething()), тогда как люди, которые начинают на других языках (С++: в частности Win32 С++) имеют тенденцию использовать другой метод по привычке: в Win32 "if (CheckSomething()) не будет работать, если CheckSomething возвращает BOOL (вместо bool); и во многих случаях функции API явно возвращают значение 0/1 int/INT, а не значение true/false (что является BOOL).

Я всегда использовал более вербальный метод, опять же по привычке. Они синтаксически одинаковы; Я не покупаю глупость, "раздражительность" меня раздражает, потому что программист не тот, который должен быть впечатлен кодом (компьютер делает). И, в реальном мире, уровень квалификации любого данного человека, который смотрит на написанный мной код, будет меняться, и у меня нет времени или желания объяснить особенности оценки высказываний тем, кто не понимает мало несущественных такие как бит.

Ответ 23

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

Я начал "исправлять" это, так как булевы самодостаточны, тогда я уронил крестовый поход... ^ _ ^ Они не любят очищать код здесь, так или иначе, утверждая, что это затрудняет интеграцию между ветвями true, но тогда вы живете вечно с плохо выглядящим кодом...).

Если вы правильно напишете свое имя переменной boolean, оно должно читаться естественно:
if (isSuccessful) vs. if (returnCode)

Я могу побаловать логическое сравнение в некоторых случаях, например:
if (PropertyProvider.getBooleanProperty(SOME_SETTING, true) == true), потому что он читает меньше "естественно".

Ответ 24

По какой-то причине мне всегда нравилось

if (IsGood)

больше, чем

if (!IsBad)

и вот почему я вроде как Ruby, если только (но это слишком легко злоупотреблять):

unless (IsBad)

и даже больше, если он используется следующим образом:

raise InvalidColor unless AllowedColors.include?(color)

Ответ 25

Cybis, при кодировании на С++ вы также можете использовать ключевое слово not. Это часть стандарта, так как давным-давно, поэтому этот код совершенно верен:

if (not foo ())
   bar ();

Edit: BTW, я забыл упомянуть, что стандарт также определяет другие логические ключевые слова, такие как и (& &), bitand (&) или (||), bitor (|), xor (^),... Они называются синонимами операторов.

Ответ 26

Я не использую ==, но когда-нибудь использую!= потому что это яснее в моем сознании. НО на моей работе мы не используем!= Или ==. Мы пытаемся получить имя, которое имеет значение с hasXYZ() или isABC().

Ответ 27

Если вы действительно думаете, что вам нужно:

if (Flag == true)

то, поскольку условное выражение само по себе является логическим, вы, вероятно, хотите его расширить:

if ((Flag == true) == true)

и т.д. Сколько еще гвоздей требуется этот гроб?

Ответ 28

Если вы работаете в perl, у вас есть возможность

unless($isGood)

Ответ 29

Мы склонны делать следующее:

if(IsGood)

или

if(IsGood == false)

Причина этого в том, что у нас есть код устаревшего кода, написанный парнем, которого больше нет (в Delphi), который выглядит так:

if not IsNotGuam then

Это вызвало у нас большую боль в прошлом, поэтому было решено, что мы всегда будем пытаться проверить положительное; если это невозможно, сравните отрицательный с ложным.

Ответ 30

Единственный раз, когда я могу думать о том, где более важен код имел смысл, был в pre -.NET Visual Basic, где true и false были фактически целыми числами (true = -1, false = 0), а булевы выражения считались ложными, если они оценивались к нулю и истинно для любых других ненулевых значений. Таким образом, в случае старого VB перечисленные два метода не были фактически эквивалентны, и если бы вы только хотели, чтобы что-то было истинным, если оно оценивалось в -1, вам пришлось явно сравнивать с "истинным". Таким образом, выражение, которое оценивается как "+1", было бы истинным, если бы оно оценивалось как целое (потому что оно не равно нулю), но оно не было бы эквивалентно "true". Я не знаю, почему VB был разработан таким образом, но я вижу много логических выражений, сравнивающих переменные с истинными и ложными в старом коде VB.