我应该使用`!IsGood`还是`IsGood == false`?

时间:2008-12-10 14:23:52

标签: language-agnostic boolean not-operator

我一直看到代码执行这样的检查

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

或者

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

我讨厌这种语法,并且总是使用以下语法。

if (IsGood)
{
   DoSomething();
}

if (!IsGood)
{
   DoSomething();
}

是否有理由使用“== true”或“== false”?

这是一个可读性的东西吗?人们只是不了解布尔变量吗?

另外,两者之间是否有任何性能差异?

41 个答案:

答案 0 :(得分:104)

我遵循与你相同的语法,它不那么详细。

人们(更初学者)更喜欢使用== true只是为了确保它是他们想要的。他们习惯于在条件中使用运算符......他们发现它更具可读性。但是一旦你变得更高级,你就会发现它很烦人,因为它太冗长了。

答案 1 :(得分:38)

当我遇到

时,我总是轻笑(或者根据我的心情向别人扔些东西)
if (someBoolean == true) { /* ... */ }

因为当然如果你不能依赖于你的比较返回一个布尔值的事实,那么你也不能依赖于将结果与true进行比较,所以代码应该变成

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

但是,当然,这应该是

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

但是,当然......

(啊,编译失败。回去工作。)

答案 2 :(得分:32)

我更喜欢更短变体。但有时== false有助于缩短您的代码:

对于使用C#2.0的项目中的真实场景,我只看到一个很好的理由:bool?类型。三态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,在C#2.0中不鼓励使用AFAIK,因为它的目的是为用户定义的类型提供类似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!");
                }
            }
        }
    }
}

所以......请谨慎使用运算符重载:(

答案 3 :(得分:18)

根据Code Complete一本书Jeff got his name from并高度重视以下是你应该对待布尔的方法。

if (IsGood)
if (!IsGood)

我习惯性地比较布尔值,但我想为什么在这个过程中添加额外的步骤并将布尔值视为第二种类型。在我看来,比较返回一个布尔值,一个布尔类型已经是一个布尔值,所以为什么不使用布尔值。

真正的争论归结为为你的布尔人使用好名字。就像你上面所做的那样,我总是将我的布尔对象用于问题。如

  • IsGood
  • 的HasValue

答案 4 :(得分:15)

如果有问题的变量确实被用作布尔值(即使它的类型不是布尔值),那么专门针对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问题,了解这个问题实际上是某个人的位置......

答案 5 :(得分:13)

我同意你的看法(我也很生气)。我认为IsGood == true评估为bool只是一个轻微的误解,这是IsGood的开头。

我经常看到SomeStringObject.ToString()附近的这些实例。

也就是说,在使用类型更宽松的语言中,这可能是合理的。但不是在C#中。

答案 6 :(得分:9)

有些人发现对已知值的显式检查更具可读性,因为您可以通过阅读推断变量类型。我不确定一个人是否比另一个更好。他们都工作。我发现如果变量固有地保持“逆”,那么我似乎倾向于检查一个值:

if(IsGood) DoSomething();

if(IsBad == false) DoSomething();

而不是

if(!IsBad) DoSomething();

但同样,对我来说并不重要,我确信它最终会成为同样的IL。

答案 7 :(得分:7)

从答案到目前为止,这似乎是共识:

  1. 在大多数情况下,短格式最好。 (IsGood和!IsGood)
  2. 布尔变量应写为正数。 (IsGood而不是IsBad)
  3. 由于大多数编译器都会以相同的方式输出相同的代码,因此除了解释语言外,没有任何性能差异。
  4. 这个问题没有明显的胜利者可能被视为编码风格的宗教战争。

答案 8 :(得分:7)

仅限可读性..

如果您喜欢的任何方式在编译成机器代码时更有效。但是我希望它们能够生成完全相同的机器代码。

答案 9 :(得分:6)

我更喜欢使用:

if (IsGood)
{
    DoSomething();
}

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

因为我发现这更具可读性 - !很容易错过(阅读和打字); “如果不是IsGood那么......”听起来听起来不对,而不是“如果IsGood是假的那么......”,这听起来更好。

答案 10 :(得分:5)

有可能(尽管不太可能,至少我希望)在C代码中,TRUE和FALSE是#defined到1和0以外的东西。例如,程序员可能决定使用0作为“true”和-1在特定的API中为“false”。遗留的C ++代码也是如此,因为“true”和“false”并不总是C ++关键字,特别是在有ANSI标准的前一天。

值得指出的是,某些语言 - 特别是像Perl,JavaScript和PHP这样的脚本 - 可以对哪些值计为true以及哪些值计为false进行有趣的解释。有可能(虽然,希望不太可能)“foo == false”意味着与“!foo”略有不同。这个问题被标记为“语言不可知”,并且一种语言可以定义==运算符以不与以下方式兼容的方式工作!操作

答案 11 :(得分:5)

我已经将以下内容视为C / C ++样式要求。

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

原因是如果你不小心把“=”而不是“==”,编译器就会为一个常量赋值。与此同时,它损害了每一个if语句的可读性。

答案 12 :(得分:4)

有时它在可读性方面有用。有时命名变量或函数调用最终可能会造成双重否定,这可能会造成混淆,并且使预期测试明确这样可能有助于提高可读性。

一个很好的例子可能是strcmp()C / C ++,如果字符串相等则返回0,否则<或者> 0,取决于差异的位置。所以你经常会看到:

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

但一般来说,我同意你的意见

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

更清楚阅读。

答案 13 :(得分:3)

为了便于阅读,您可能会考虑依赖于其他属性的属性:

public bool IsBad => !IsGood;

然后,你真的可以理解:

if (IsBad)
{
    ...
}

答案 14 :(得分:3)

我更喜欢!IsGood 方法,我认为大多数来自c风格语言背景的人也会更喜欢它。我只是在这里猜测,但我认为大多数写 IsGood == False 的人来自像Visual Basic这样更冗长的语言背景。

答案 15 :(得分:3)

!IsGood模式在缩减为正则表达式时比IsGood == false更容易找到。

/\b!IsGood\b/

VS

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

答案 16 :(得分:3)

唯一更糟的是

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

永远不要理解这种方法背后的想法。

答案 17 :(得分:3)

我更喜欢!IsGood,因为对我而言,它更清晰,更明确。检查boolean == true是否多余,所以我会避免这种情况。从语法上讲,我不认为检查IsGood == false是否存在差异。

答案 18 :(得分:2)

你忘了:

  

if(IsGood == FileNotFound

答案 19 :(得分:2)

在许多语言中,不同之处在于,在一种情况下,您使编译器/解释器指示true或false的含义,而在另一种情况下,它由代码定义。 C就是一个很好的例子。

if (something) ...

在上面的例子中,“something”与编译器的“true”定义进行了比较。通常这意味着“不为零。”

if (something == true) ...

在上面的例子中,“某事物”被比作“真实”。 “true”的类型(以及可比性)和“true”的值都可以由语言和/或编译器/解释器定义,也可以不定义。

两者通常不一样。

答案 20 :(得分:1)

如果你真的认为你需要:

if (Flag == true)

然后因为条件表达式本身就是布尔值,你可能想把它扩展为:

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

等等。这棺材需要多少钉子?

答案 21 :(得分:1)

我不使用==,但有时我会使用!=因为它在我的脑海中更清晰。但在我的工作中,我们不使用!===。如果使用hasXYZ()isABC(),我们会尝试获得一个有意义的名称。

答案 22 :(得分:1)

Cybis,在C ++中编码时,您也可以使用 not 关键字。很久以前它就是标准的一部分,所以这段代码完全有效:

if (not foo ())
   bar ();

编辑:BTW,我忘了提到标准还定义了其他布尔关键字,例如(&amp;&amp;), bitand (&amp;),< em>或(||), bitor (|), xor (^)......它们被称为运算符同义词。

答案 23 :(得分:1)

如果你碰巧在perl工作,你可以选择

unless($isGood)

答案 24 :(得分:1)

啊,我有一些共同支持更长的形式,认为它比微小的更可读!

我开始“修复”了,因为布道是自给自足的,然后我放弃了十字军东征...... ^ _ ^他们不喜欢在这里清理代码,无论如何,争论它使分支之间的整合变得困难(那是是的,但是你会因为看起来不好的代码而永远活着......)。

如果你正确地写了你的布尔变量名,它应该自然地阅读:
if (isSuccessful)if (returnCode)

在某些情况下,我可能会沉迷于布尔比较,例如:
if (PropertyProvider.getBooleanProperty(SOME_SETTING, true) == true)因为它“读起来不那么自然”。

答案 25 :(得分:1)

就个人而言,我更喜欢鲍勃叔叔在清洁代码中谈到的形式:

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

bool ShouldDoSomething()
{
    return IsGood;
}

其中条件,除了最简单的条件,都放在谓词函数中。然后重要的是布尔表达式的实现的可读性。

答案 26 :(得分:1)

在我看来(虽然我没有证据支持这一点),从C#/ java类型语言开始的人更喜欢“if(CheckSomething())”方法,而以其他语言开始的人(C ++) :特别是Win32 C ++)倾向于使用习惯中的另一种方法:在Win32中“if(CheckSomething())”如果CheckSomething返回BOOL(而不是bool)将不起作用;在许多情况下,API函数显式返回0/1 int / INT而不是true / false值(这就是BOOL)。

我总是习惯于使用更冗长的方法。它们在语法上是一样的;我不买“冗长的烦恼我”的废话,因为程序员不是需要被代码(计算机确实)留下深刻印象的程序员。而且,在现实世界中,任何看到我编写的代码的人的技能水平都会有所不同,而我没有时间或倾向于向可能不了解不重要的人解释陈述评价的特殊性像这样的位。

答案 27 :(得分:1)

由于某些原因,我一直很喜欢

if (IsGood)

超过

if (!IsBad)

这就是为什么我喜欢Ruby的原因除非(但它有点太容易被滥用):

unless (IsBad)

如果像这样使用甚至更多:

raise InvalidColor unless AllowedColors.include?(color)

答案 28 :(得分:0)

这两种形式在语义上是相同的,并产生相同的机器代码,那么为什么不使用更具可读性的呢?

if (IsGood == false)优于if(!IsGood)

扫描代码时,很容易误认为“!”在bool变量中的字符的bool变量之前。

答案 29 :(得分:0)

虽然这不是一个实际的区别,但我总是将==视为数字运算符,因此它不适用于布尔类型。最接近的布尔运算符是“等价”(非独占或),它没有C样式运算符。

这样严格的布尔测试变为

if (!(IsGood ^ true))

作为布尔数字运算符问题的一个例子,

的布尔值是什么
true / 2

答案 30 :(得分:0)

我唯一能想到更多的vebose代码有意义的地方是在.NET之前的Visual Basic中,其中true和false实际上是整数(true = -1,false = 0),如果布尔表达式被评估,则认为它们是假的对于任何其他非零值,为零和为真。所以,在旧的VB的情况下,列出的两个方法实际上并不等同,如果你只想要一些事情,如果它被评估为-1,你必须明确地比较'true'。因此,如果求值为整数(因为它不为零),则求值为“+1”的表达式将为真,但它不等于“true”。我不知道为什么VB是这样设计的,但我看到很多布尔表达式在旧VB代码中将变量与true和false进行比较。

答案 31 :(得分:0)

我认为这实际上取决于语言。

比如说,在PHP中,某些函数可以返回false,并返回非负数。

然后是:

if(foo(bar)) { ... }

方案不能很好地工作,因为你无法判断返回false还是0。

在没有这个令人讨厌的小FUBAR的其他语言中,我认为任何一种形式都是可以接受的。

答案 32 :(得分:0)

只要我们有if (isGood)if (!isGood)就可以了。

有时我遇到这样的代码......

if (!getGreatGrandFateher.getGrandFather().getFather().getFirstChild().isMale())
{
   doSomething();
}

乍一看,这会误导doSomething如果是男性则会被调用。小'​​!'在“if”在上面的大代码构造中迷失之后。

下面的明确检查提供了更好的可读性

if(getGreatGrandFateher.getGrandFather().getFather().getFirstChild().isMale() == false)
{
   doSomething();
}

答案 33 :(得分:0)

一种尺码并不适合所有人。有时一个更简洁的形式可以说是简单的或惯用的,比如!(x%y),如果y是x的因子,则返回“True”。

其他时候,更明确的比较会更有用。 [(x,y)对于范围(10)中的x,对于范围(10)中的y,如果不是(x和y)],则y的范围(y,y)范围内的x的范围(x,y)不如(10)if(x == 0或y == 0)]

答案 34 :(得分:0)

我们倾向于在此处执行以下操作:

if(IsGood)

if(IsGood == false)

之所以这样,是因为我们有一些遗留代码由一个不再在这里(在Delphi中)的人编写,看起来像:

if not IsNotGuam then

这给我们带来了很大的痛苦,所以我们决定总是试图检查积极因素;如果那是不可能的,那么将消极与假比较。

答案 35 :(得分:0)

在像C这样没有“布尔”类型的语言中,我推荐更长的方式,即

if (is_good == True)
{
}

原因是is_good不仅true / false(很可能实现为char),因此可能被其他值损坏或未正确设置。

这有什么用呢?你的代码将能够解决is_good被错误设置的任何问题,因为没有== True或== False检查任何东西都会为true;)如果你真的是指一个布尔值那么那就不好了。

答案 36 :(得分:0)

我喜欢根据变量的命名使用不同的样式,例如:

以Is,Has等前缀命名的变量通过查看名称显而易见,我使用的是布尔值:

if(IsSomething)

但如果我有没有这种前缀的变量,我想使用

if(Something == true)

您使用的是哪种形式,您应该根据您使用的编程语言来决定。

的含义
if(Something) and if(Something == true)

在不同的编程语言中可能有不同的含义。

答案 37 :(得分:0)

有人可能认为像ifValidDate == true这样的测试会导致过度使用。考虑一块代码块,它验证我们是否拥有来自用户的有效数据,例如:

if (isValidDate == true) {
    if (isValidQuantity == true) {
         if (isOtherThingValid == true) {
              bool result = doThing();
              if (result == true) {
                   thatWorked();
         } // long block of code that tries to compensate for OtherThing's invalidness
    } // obtuse function call to a third party library to send an email regarding the invalid quantity
} // is this the function close brace or the if...

这让我发疯,这也是我养成了反过来做事习惯的部分原因:

if (isValidDate == false) {
    logThisProblem("Invalid date provided.");
    return somethingUseful;
}

if (isValidQuantity == false) {
    logThisProblem("Invalid quantity provided.");
    return somethingUseful;
}

if (isOtherThingValid == false) {
    logThisProble("Other thing not valid.");
    return somethingUseful;
}

// OK ... we've made it this far...
bool result = doThing(date, quantity, otherThing);

答案 38 :(得分:0)

在某些情况下,这样做实际上很有用,但并不常见。

这是一个例子。在Actionscript 2中,布尔值有3个可能的值:

  • 空/未定义

我通常会在采用可选布尔参数的方法中执行类似的操作:

function myFunc(b:Boolean):Void {
  if(b == true) {
    // causes b to default to false, as null/undefined != true
  }
}

OR

function myFunc(b:Boolean):Void {
  if(b != false) {
    // causes b to default to true, as null/undefined != false
  }
}

取决于我想要将值默认为。虽然如果我需要多次使用布尔值,我会做这样的事情:

function myFunc(b:Boolean):Void {
  b = (b == true); // default to false
}

OR

function myFunc(b:Boolean):Void {
  b = (b != false); // default to true
}

答案 39 :(得分:-1)

在C#/ C ++ / Java / etc中编码...我总是喜欢

if (something == true)
if (something == false)

if (something)
if (!something)

因为感叹号很难一目了然,除非我使用大字体(但我会在页面上看到更少的代码 - 我们所有人都买不起24“+显示器)。我特别喜欢喜欢不一致并使用if (something)if (something == false)

但是,当我使用Python编写代码时,我几乎总是喜欢

if something:
if not something:

因为'not'显而易见。

答案 40 :(得分:-2)

我会

if (isGood) {
  doSomething();
}

if (isNotGood) {
    doSomethngElse();
}

读得更好。