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

chi*_*s42 46 language-agnostic boolean not-operator

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

if (IsGood == false)
{
   DoSomething();
}
Run Code Online (Sandbox Code Playgroud)

或这个

if (IsGood == true)
{
   DoSomething();
}
Run Code Online (Sandbox Code Playgroud)

我讨厌这种语法,并始终使用以下语法.

if (IsGood)
{
   DoSomething();
}
Run Code Online (Sandbox Code Playgroud)

要么

if (!IsGood)
{
   DoSomething();
}
Run Code Online (Sandbox Code Playgroud)

有没有理由使用' == true'或' == false'?

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

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

Pat*_*ins 104

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

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

  • 56票几乎是琐碎的意见?哈,这个网站是失控的. (9认同)
  • 当我看到==对于布尔类型时,我认为这是一个指示器,使用==的人确实完全理解布尔逻辑及其含义. (5认同)
  • 如果正确命名变量,那么添加运算符实际上会降低可读性.即,当你阅读它时,"如果是好的"比"如果好是真的"更具可读性.我跟"if(isGood)"一样,尽可能清楚. (2认同)

Rob*_*iam 38

当我遇到时,我总是轻笑(或者根据我的心情向别人扔东西)

if (someBoolean == true) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

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

if ((someBoolean == true) == true) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

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

if (((someBoolean == true) == true) == true) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

但是当然 ...

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

  • Monty Python的阴影和垃圾邮件草图......我想要一个使用垃圾邮件,垃圾邮件,垃圾邮件,真实和垃圾邮件的If测试..... (3认同)

Igo*_*orK 32

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

对于使用C#2.0的项目中的真实场景,我只看到一个很好的理由:bool?类型.三态bool?是有用的,很容易通过这种方式检查其中一个可能的值.

其实你不能使用(!IsGood),如果IsGoodbool?.但写作(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");
}
Run Code Online (Sandbox Code Playgroud)

还有一个我刚刚发现的案例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!");
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Nic*_*rdi 18

根据Code Complete的一本书杰夫得到了他的名字并高度关注以下是你应该对待布尔人的方式.

if (IsGood)
if (!IsGood)
Run Code Online (Sandbox Code Playgroud)

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

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

  • 很好
  • 的HasValue
  • 等等


Mic*_*urr 15

如果有问题的变量确实被用作布尔值(即使它的类型不是布尔值),那么专门针对true或false进行测试的技术肯定是不好的做法 - 特别是在C/C++中.针对truecan(可能会)的测试会导致细微的错误:

这些明显相似的测试给出了相反的结果:

// 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;
}
Run Code Online (Sandbox Code Playgroud)

这将显示以下结果:

isGood != true
isGood is true
Run Code Online (Sandbox Code Playgroud)

如果你觉得需要测试用作反对true/false的布尔标志的变量(在我看来不应该这样做),你应该使用始终测试的成语为false,因为false只能有一个值(0)而true可以有多个可能的值(除了以外的任何值0):

if (isGood != false) ...  // instead of using if (isGood == true)
Run Code Online (Sandbox Code Playgroud)

有些人会认为这是C/C++中的一个缺陷,这可能是真的.但是这些语言(以及可能还有许多其他语言)都是生活中的事实所以我会坚持使用简短的习语,即使在像C#这样的语言中也不允许你使用整数值作为布尔值.

看到这个问题的例子,这个问题实际上是某个人...


Mic*_*ren 13

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

我经常看到这些近似的例子SomeStringObject.ToString().

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


cta*_*cke 9

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

if(IsGood) DoSomething();
Run Code Online (Sandbox Code Playgroud)

要么

if(IsBad == false) DoSomething();
Run Code Online (Sandbox Code Playgroud)

代替

if(!IsBad) DoSomething();
Run Code Online (Sandbox Code Playgroud)

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


ada*_*dam 7

仅限可读性..

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


chi*_*s42 7

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

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

  • 我不同意没有明显的赢家 - 特别是在C/C++中.这不仅仅是一个风格问题,还可能存在语义差异.使用较长的形式可能会导致细微的错误. (4认同)

小智 6

我更喜欢使用:

if (IsGood)
{
    DoSomething();
}
Run Code Online (Sandbox Code Playgroud)

if (IsGood == false)
{
    DoSomething();
}
Run Code Online (Sandbox Code Playgroud)

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


Par*_*ppa 5

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

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


小智 5

我已经看到以下作为C/C++样式的要求.

if ( true == FunctionCall()) {
  // stuff
}
Run Code Online (Sandbox Code Playgroud)

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