C# 使用 == 或 .Equals() 进行布尔比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13614839/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:11:15  来源:igfitidea点击:

Using == or .Equals() for bool comparison

c#

提问by Ryan Kohn

I was reviewing some code, and I found something that looked like this:

我正在一些代码,我发现了一些看起来像这样的东西:

public class MyClass
{
    public bool IsEditable { get; set; }

    public void HandleInput()
    {
        if (IsEditable.Equals(false))
        {
            //do stuff
        }
    }
}

As far as I know, (IsEditable.Equals(false))is identical to (IsEditable == false)(and also the same as (!IsEditable)).

据我所知,(IsEditable.Equals(false))与 相同(IsEditable == false)(也与 相同(!IsEditable))。

Besides personal preference, is there any difference at all between .Equals()and ==, specifically when used to compare bools?

除了个人喜好之外,.Equals()and之间是否有任何区别==特别是在用于比较bools 时

采纳答案by dasblinkenlight

The Equalsway appears to be significantly slower - roughly 2.7 times in debug mode, and more than seven times in release mode.

这种Equals方式似乎要慢得多——在调试模式下大约是 2.7 倍,在发布模式下大约是 7 倍。

Here is my quick and dirty benchmark:

这是我快速而肮脏的基准测试:

public static void Main() {
    bool a = bool.Parse("false");
    bool b = bool.Parse("true");
    bool c = bool.Parse("true");
    var sw = new Stopwatch();
    const int Max = 1000000000;
    int count = 0;
    sw.Start();
    // The loop will increment count Max times; let's measure how long it takes
    for (int i = 0; i != Max; i++) {
        count++;
    }
    sw.Stop();
    var baseTime = sw.ElapsedMilliseconds;
    sw.Start();
    count = 0;
    for (int i = 0; i != Max; i++) {
        if (a.Equals(c)) count++;
        if (b.Equals(c)) count++;
    }
    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds - baseTime);
    sw.Reset();
    count = 0;
    sw.Start();
    for (int i = 0; i != Max; i++) {
        if (a==c) count++;
        if (b==c) count++;
    }
    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds - baseTime);
    sw.Reset();
    count = 0;
    sw.Start();
    for (int i = 0; i != Max; i++) {
        if (!a) count++;
        if (!b) count++;
    }
    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds - baseTime);
}

Running this produces the following results:

运行它会产生以下结果:

In debug mode

在调试模式

8959
2950
1874

In release mode

在发布模式

5348
751
7

Equalsappears to be the slowest. There appears to be little difference between ==and !=. However, if (!boolExpr)appears to be the clear winner.

Equals似乎是最慢的。==和之间似乎没有什么区别!=。然而,if (!boolExpr)似乎是明显的赢家。

回答by Sam I am says Reinstate Monica

This is mostly a readability issue. I'd normally use ==because that's what I'm used to looking at.

这主要是一个可读性问题。我通常会使用,==因为那是我习惯看的东西。

Specifically with bools, you don't have to compare them at all

特别是对于布尔值,您根本不必比较它们

if(!IsEditable)

will suffice

就足够了

although, Sometimes I myself do write things like if (val == false)just to be extra sure that i don't misread it when i have to modify the code.

尽管如此,有时我自己if (val == false)也会写一些东西,比如为了确保在我必须修改代码时不会误读它。

回答by Keith Nicholas

In this case, with bools, it doesn't make any difference, however with other built-in non reference types it can.

在这种情况下,对于 bool,它没有任何区别,但是对于其他内置的非引用类型,它可以。

==allows for conversions of types if it can .Equalswon't

==如果不能,.Equals则允许类型转换

回答by Robert H

Take a look at the following quote Taken from here:

看看下面摘自这里的报价:

The Equals method is just a virtual one defined in System.Object, and overridden by whichever classes choose to do so. The == operator is an operator which can be overloaded by classes, but which usually has identity behaviour.

For reference types where == has not been overloaded, it compares whether two references refer to the same object - which is exactly what the implementation of Equals does in System.Object.

Equals 方法只是在 System.Object 中定义的一个虚拟方法,并被任何选择这样做的类覆盖。== 运算符是一个可以被类重载的运算符,但它通常具有标识行为。

对于 == 没有被重载的引用类型,它比较两个引用是否引用同一个对象——这正是 System.Object 中 Equals 的实现所做的。

So in short, Equalsis really just doing a == anyways.

所以简而言之,Equals实际上只是在做一个 == 反正。

回答by Oliver Hanappi

In fact, for basic types such as int, booletc. there is a difference between calling Equals()and ==due to the fact that the CIL has instructions for handling such types. Calling Equals()forces boxing of the value and making a virtual method call, whereas usage of ==leads to usage of a single CIL instruction.

事实上,对于诸如intbool等的基本类型Equals()==由于 CIL 具有处理此类类型的指令,因此调用和之间存在差异。调用Equals()强制对值进行装箱并进行虚拟方法调用,而使用==会导致使用单个 CIL 指令。

!valueand value == falseis actually the same, at least in Microsoft's C# compiler bundled with .NET 4.0.

!value并且value == false实际上是相同的,至少在与 .NET 4.0 捆绑在一起的 Microsoft 的 C# 编译器中是这样。

Hence, the comparisons within the following methods

因此,以下方法中的比较

public static int CompareWithBoxingAndVirtualMethodCall(bool value)
{
    if (value.Equals(false)) { return 0; } else { return 1; }
}

public static int CompareWithCILInstruction(bool value)
{
    if (value == false) { return 0; } else { return 1; }
    if (!value) { return 0; } else { return 1; } // comparison same as line above
}

will compile to to the following CIL instructions:

将编译为以下 CIL 指令:

// CompareWithBoxingAndVirtualMethodCall

ldarga.s 'value'
ldc.i4.0
call instance bool [mscorlib]System.Boolean::Equals(bool) // virtual method call
brfalse.s IL_000c // additional boolean comparison, jump for if statement

// CompareWithCILInstruction

ldarg.0
brtrue.s IL_0005 // actual single boolean comparison, jump for if statement

回答by Nicholas Carey

If you decompile System.Boolean and look at it, It's Equals overloads are defined thus:

如果你反编译 System.Boolean 并查看它,It's Equals 重载定义如下:

public override bool Equals(object obj)
{
  if (!(obj is bool))
    return false;
  else
    return this == (bool) obj;
}

public bool Equals(bool obj)
{
  return this == obj;
}

I would like to think the C# compiler's optimizer and the .Net JIT compiler would be smart enough to inline these, at least for release/optimized compilations, making them exactly the same.

我认为 C# 编译器的优化器和 .Net JIT 编译器足够聪明,可以内联这些,至少对于发布/优化编译,使它们完全相同。

回答by pramod

==is always better than .Equals. In the case of integer comparison, ==runs faster than .Equals. In the below test, the elapsed time using ==157, while for .Equalsthe elapsed time is 230.

==总是比.Equals. 在整数比较的情况下,==运行速度比.Equals. 在下面的测试中,经过的时间使用==157,而.Equals经过的时间是 230。

class Program
 {        
   static void Main(string[] args)
    {

        Program programObj = new Program();
            programObj.mymethod();
            programObj.mynextmethod();

    }
    void mynextmethod()
    {
        var watch = Stopwatch.StartNew();

        for (int i = 0; i < 60000000; i++)
        {
            int j = 0;
            if (i.Equals(j))

                j = j + 1;
        }
        watch.Stop();
        var elapsedMs = watch.ElapsedMilliseconds;
        Console.WriteLine("Time take in method" + elapsedMs);


        Console.ReadLine();
    }
    void mymethod()
    {
        var watch = Stopwatch.StartNew();

        for (int i = 0; i < 60000000; i++)
        {
            int j = 0;
            if (i == j)

                j = j + 1;
        }
        watch.Stop();
        var elapsedMs = watch.ElapsedMilliseconds;
        Console.WriteLine("Time take in method" + elapsedMs);
    }
}