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

Я продолжаю видеть код, который делает такие проверки

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

или это

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

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

if (IsGood)
{
   DoSomething();
}

или

if (!IsGood)
{
   DoSomething();
}

есть ли причина, чтобы использовать '== true' или '== false'?

это читаемость вещь? Люди просто не понимают булевых переменных?

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

30 ответов


Я следую тому же синтаксису, что и вы, это менее многословно.

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


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

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

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

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

но, конечно, это должно быть

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

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

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


я бы предпочел короче вариант. Но иногда ... --2--> помогает сделать ваш код еще короче:

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

на самом деле вы не можете использовать (!IsGood) если IsGood is bool?. Но писать!--8--> хуже (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 не рекомендуется в C# 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!");
                }
            }
        }
    }
}

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


по данным Код книги Джефф получил свое имя от и держит в высоких отношениях следующее, Как вы должны относиться к логическим.

if (IsGood)
if (!IsGood)

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

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

  • IsGood
  • свойство hasvalue
  • etc.

метод тестирования специально против true или false определенно является плохой практикой, если рассматриваемая переменная действительно должна использоваться как логическое значение (даже если ее тип не является логическим) - особенно в C/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, потому что false может иметь только одно значение (0) в то время как true может иметь несколько возможных значений (что угодно, кроме 0):

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

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

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


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

Я часто вижу этих случаях SomeStringObject.ToString().

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


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

if(IsGood) DoSomething();

или

if(IsBad == false) DoSomething();

вместо

if(!IsBad) DoSomething();

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


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

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


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

  1. короткая форма лучше всего в большинстве случаев. (И хорошая !IsGood)
  2. логические переменные должны быть написаны как положительные. (Хорошая, а не плохо)
  3. поскольку большинство компиляторов будут выводить один и тот же код в любом случае, разницы в производительности нет, за исключением интерпретируемых языков.
  4. этот вопрос не имеет явного победителя, вероятно, можно рассматривать как битву в религиозная война стиля кодирования.

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

if (IsGood)
{
    DoSomething();
}

и

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

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


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

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


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

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

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


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

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

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

вообще однако я согласен с вами это

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

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


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


только хуже

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

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


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

/\b!IsGood\b/

vs

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

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

public bool IsBad => !IsGood;

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

if (IsBad)
{
    ...
}

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


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

if (something) ...

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

if (something == true) ...

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

часто эти два не то же самое.


вы забыли:

if (IsGood ==FileNotFound)


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

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


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

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

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

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


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

if (IsGood)

больше, чем

if (!IsBad)

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

unless (IsBad)

и даже больше, если использовать так:

raise InvalidColor unless AllowedColors.include?(color)

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

if (not foo ())
   bar ();

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


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

if (Flag == true)

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

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

и так далее. Сколько еще гвоздей нужно этому гробу?


Если вы работаете в perl, у вас есть опция

unless($isGood)

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


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

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

bool ShouldDoSomething()
{
    return IsGood;
}

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


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

if(IsGood)

или

if(IsGood == false)

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

if not IsNotGuam then

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