47

我不断看到执行这样检查的代码

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

或这个

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

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

if (IsGood)
{
   DoSomething();
}

或者

if (!IsGood)
{
   DoSomething();
}

有任何理由使用' == true'或' == false'吗?

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

另外,两者之间有性能差异吗?

4

41 回答 41

103

我遵循与您相同的语法,它不那么冗长。

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

于 2008-12-10T14:26:26.430 回答
40

当我遇到

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

因为当然,如果您不能依赖比较返回布尔值这一事实,那么您也不能依赖将结果与 true 进行比较,因此代码应该变为

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

但是,当然,这真的应该是

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

但是当然 ...

(啊,编译失败。重新开始工作。)

于 2008-12-10T15:55:45.297 回答
32

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

对于使用 C# 2.0 的项目中的实际场景,我认为只有一个很好的理由这样做:bool?类型。三态bool?很有用,并且很容易以这种方式检查其可能值之一。

实际上你不能使用(!IsGood)if IsGoodis 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");
}

还有一种情况我刚刚发现 whereif (!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!");
                }
            }
        }
    }
}

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

于 2008-12-10T14:31:17.620 回答
18

根据Code Complete一本书,Jeff 得名并高度重视以下是您应该处理布尔值的方式。

if (IsGood)
if (!IsGood)

我习惯于实际比较布尔值,但我想为什么要在过程中添加一个额外的步骤并将布尔值视为二流类型。在我看来,比较返回一个布尔值,而布尔类型已经是一个布尔值,所以为什么不直接使用布尔值。

真正的争论归结为为你的布尔值使用好名字。就像你在上面所做的那样,我总是用问题的 for 来表达我的布尔对象。如

  • 很好
  • 有值
  • 等等
于 2008-12-10T14:35:27.347 回答
15

如果所讨论的变量确实应该用作布尔值(即使它的类型不是布尔值),那么专门针对真假进行测试的技术绝对是不好的做法——尤其是在 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 问题...

于 2008-12-10T16:39:09.373 回答
13

我同意你的看法(我也对此感到恼火)。我认为这只是一个轻微的误解,IsGood == true评估为 bool,这是IsGood开始的。

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

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

于 2008-12-10T14:27:19.530 回答
9

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

if(IsGood) DoSomething();

或者

if(IsBad == false) DoSomething();

代替

if(!IsBad) DoSomething();

但同样,这对我来说并不重要,而且我确信它最终会成为同一个 IL。

于 2008-12-10T14:29:21.103 回答
7

仅可读性..

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

于 2008-12-10T14:27:33.120 回答
7

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

  1. 在大多数情况下,简短的形式是最好的。(IsGood 和 !IsGood)
  2. 布尔变量应写为正数。(IsGood 而不是 IsBad)
  3. 由于大多数编译器会以任何一种方式输出相同的代码,因此没有性能差异,除了解释型语言。
  4. 这个问题没有明确的赢家,大概可以看作是编码风格的宗教战争。
于 2008-12-10T17:19:52.320 回答
6

我更喜欢使用:

if (IsGood)
{
    DoSomething();
}

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

因为我发现这更具可读性 - !太容易错过(在阅读和打字方面);还有“if not IsGood then...”听起来不太对劲,而不是“if IsGood is false then...”听起来更好。

于 2008-12-10T17:20:25.907 回答
5

有可能(尽管不太可能,至少我希望如此)在 C 代码中 TRUE 和 FALSE 被 #定义为 1 和 0 以外的事物。例如,程序员可能决定将 0 用作“真”,将 -1 用作“假” " 在特定的 API 中。遗留 C++ 代码也是如此,因为“true”和“false”并不总是 C++ 关键字,尤其是在 ANSI 标准出现之前。

还值得指出的是,某些语言——尤其是像 Perl、JavaScript 和 PHP 这样的脚本语言——可以对哪些值算为真和哪些值算作假有有趣的解释。“foo == false”的含义可能与“!foo”有细微的不同(尽管希望不大)。这个问题被标记为“语言不可知论”,一种语言可以定义 == 运算符,使其不能以与 ! 兼容的方式工作。操作员。

于 2008-12-10T16:01:08.250 回答
5

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

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

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

于 2008-12-10T18:51:43.007 回答
4

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

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

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

但总的来说,我同意你的看法

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

阅读起来更清晰。

于 2008-12-10T14:28:58.827 回答
3

我更喜欢!IsGood,因为对我来说,它更清晰和简洁。检查是否 aboolean == true是多余的,所以我会避免这种情况。虽然在语法上,我认为检查 if 没有区别IsGood == false

于 2008-12-10T14:26:23.947 回答
3

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

于 2008-12-10T14:37:22.100 回答
3

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

public bool IsBad => !IsGood;

然后,您就可以真正理解含义:

if (IsBad)
{
    ...
}
于 2008-12-10T15:02:03.160 回答
3

唯一更糟糕的是

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

从来不明白这种方法背后的想法。

于 2008-12-10T18:21:47.997 回答
3

与简化为正则表达式相比,该!IsGood模式更容易找到。IsGood == false

/\b!IsGood\b/

对比

/\bIsGood\s*==\s*false\b/
/\bIsGood\s*!=\s*true\b/
/\bIsGood\s*(?:==\s*false|!=\s*true)\b/
于 2008-12-10T19:18:37.807 回答
2

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

if (something) ...

在上面的示例中,“某事”与编译器对“真”的定义进行了比较。通常这意味着“不为零”。

if (something == true) ...

在上面的例子中,“something”与“true”进行了比较。“真”的类型(以及可比性)和“真”的值可能由语言和/或编译器/解释器定义,也可能不定义。

通常两者并不相同。

于 2008-12-10T17:41:25.897 回答
2

你忘了:

如果(IsGood == FileNotFound

于 2008-12-10T21:55:46.787 回答
1

就个人而言,我更喜欢 Bob 大叔在 Clean Code 中谈到的形式:

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

bool ShouldDoSomething()
{
    return IsGood;
}

其中,除了最琐碎的条件之外,条件句都放在谓词函数中。那么布尔表达式的实现的可读性就不那么重要了。

于 2008-12-10T14:30:18.497 回答
1

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

再次,出于习惯,我总是使用更详细的方法。它们在语法上是相同的;我不相信“冗长使我恼火”的废话,因为程序员不是需要被代码打动的人(计算机需要)。而且,在现实世界中,查看我编写的代码的任何特定人员的技能水平都会有所不同,而且我没有时间或倾向向可能不了解一点不重要的人解释语句评估的特殊性像这样的位。

于 2008-12-10T14:42:16.427 回答
1

啊,我有一些同事喜欢较长的形式,认为它比小形式更具可读性!

我开始“修复”这个问题,因为布尔值是自给自足的,所以我放弃了十字军东征...... ^_^ 他们不喜欢在这里清理代码,无论如何,他们认为这使得分支之间的集成变得困难(这是真的,但是那么你永远生活在丑陋的代码中......)。

如果你正确地写出你的布尔变量名,它应该自然地读起来:
if (isSuccessful)vs.if (returnCode)

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

于 2008-12-10T16:30:18.910 回答
1

不知为何我一直很喜欢

if (IsGood)

多于

if (!IsBad)

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

unless (IsBad)

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

raise InvalidColor unless AllowedColors.include?(color)
于 2008-12-10T16:53:46.037 回答
1

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

if (not foo ())
   bar ();

编辑:顺便说一句,我忘了提到该标准还定义了其他布尔关键字,例如and (&&)、bitand (&)(||)、bitor (|)、xor (^)...它们被称为运算符同义词。

于 2008-12-10T21:18:22.883 回答
1

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

于 2008-12-11T14:30:15.907 回答
1

如果你真的认为你需要:

if (Flag == true)

那么由于条件表达式本身是布尔值,您可能希望将其扩展为:

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

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

于 2009-10-30T17:33:46.723 回答
1

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

unless($isGood)
于 2009-10-30T17:51:31.290 回答
0

我们倾向于在这里做以下事情:

if(IsGood)

或者

if(IsGood == false)

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

if not IsNotGuam then

这在过去给我们带来了很大的痛苦,所以我们决定总是尝试检查阳性;如果那不可能,那么将否定与错误进行比较。

于 2008-12-10T14:43:55.317 回答
0

唯一一次我能想到更冗长的代码有意义的地方是在 .NET Visual Basic 之前的版本中,其中 true 和 false 实际上是整数(true=-1,false=0),如果布尔表达式求值为 0 和对任何其他非零值都为真。因此,在旧 VB 的情况下,列出的两种方法实际上并不等效,如果您只希望某些东西在评估为 -1 时为真,则必须明确比较“真”。因此,如果计算为整数(因为它不为零),则计算结果为“+1”的表达式将为真,但它不等于“真”。我不知道为什么 VB 是这样设计的,但我看到很多布尔表达式在旧的 VB 代码中将变量与真假进行比较。

于 2008-12-10T15:12:40.923 回答
0

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

这样严格的布尔测试就变成了

if (!(IsGood ^ true))

作为布尔数值运算符问题的说明,什么是布尔值

true / 2
于 2008-12-10T15:47:24.767 回答
0

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

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

扫码时,很容易弄错“!” 在 bool 变量中的字符的 bool 变量之前。

于 2008-12-10T16:08:12.277 回答
0

在某些情况下,这样做实际上是有用的,尽管并不经常。

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

  • 真的
  • 错误的
  • 空/未定义

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

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

或者

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
}

或者

function myFunc(b:Boolean):Void {
  b = (b != false); // default to true
}
于 2008-12-10T16:10:04.893 回答
0

我认为这真的取决于语言。

比如说,在 PHP 中,某些函数要么返回 false,要么返回非负数。

然后:

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

方案不会很好地工作,因为您无法区分返回 false 或 0。

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

于 2008-12-10T22:10:16.570 回答
0

只要我们有if (isGood)if (!isGood)它都可以。

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

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

乍一看这会误导,doSomething如果它是男性的话。小'​​!' 在“if”在像上面这样的大代码结构中迷失之后。

像下面这样的显式检查提供了更好的可读性

if(getGreatGrandFateher.getGrandFather().getFather().getFirstChild().isMale() == false)
{
   doSomething();
}
于 2008-12-11T08:13:35.447 回答
0

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

其他时候,更明确的比较会更有用。[(x, y) for x in range(10) for y in range(10) if not (x and y)] 不像 [(x, y) for x in range(10) for y in range (10) 如果 (x == 0 或 y == 0)]

于 2008-12-11T08:56:40.400 回答
0

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

if (is_good == True)
{
}

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

那么这有什么好处呢?您的代码将能够发现任何is_good设置不正确的问题,因为没有 == True 或 == False 检查任何东西都会为 true ;) 如果你真的是指布尔值,那就太糟糕了。

于 2008-12-12T22:10:02.333 回答
0

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

以 Is、Has 等前缀命名的变量通过查看名称很明显是我使用的布尔值:

if(IsSomething)

但是如果我有没有我喜欢使用的前缀的变量

if(Something == true)

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

if(Something) and if(Something == true)

在不同的编程语言中可以有非常不同的含义。

于 2008-12-13T16:53:30.303 回答
0

有人可能会争辩说,像 if isValidDate==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);
于 2009-10-16T00:33:24.160 回答
-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:

因为“不”是显而易见的。

于 2008-12-10T19:12:44.337 回答
-2

我会

if (isGood) {
  doSomething();
}

if (isNotGood) {
    doSomethngElse();
}

读起来更好。

于 2009-10-16T00:41:57.233 回答