Должен ли я использовать `! 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)
Я использую, чтобы фактически сравнивать логические значения, но я решил, что добавляет дополнительный шаг к процессу и обрабатывает булевы как второстепенные типы. По моему мнению, сравнение возвращает логическое значение, а булевский тип уже является логическим, поэтому почему бы просто не использовать логическое значение.
На самом деле дебаты сводятся к использованию хороших имен для ваших логических объектов. Как вы делали выше, я всегда формулирую свои логические объекты в вопросе. Например,
Ответ 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.