我正在审核一些代码,我发现了一些看起来像这样的东西:
public class MyClass
{
public bool IsEditable { get; set; }
public void HandleInput()
{
if (IsEditable.Equals(false))
{
//do stuff
}
}
}
据我所知,(IsEditable.Equals(false))
与(IsEditable == false)
相同(也与(!IsEditable)
相同。)
除了个人偏好之外,.Equals()
和==
之间是否存在任何差异,特别是用于比较bool
s 时?
答案 0 :(得分:10)
这主要是一个可读性问题。我通常会使用==
,因为这就是我以前所看到的。
特别是对于bool,你根本不需要比较它们
if(!IsEditable)
就足够了
虽然,有时我自己会写if (val == false)
之类的东西,只是为了确保在我必须修改代码时不会误读它。
答案 1 :(得分:8)
事实上,对于int
,bool
等基本类型,由于CIL有说明,因此调用Equals()
和==
之间存在差异用于处理此类型。调用Equals()
强制限制值并进行虚拟方法调用,而使用==
会导致使用单个CIL指令。
!value
和value == false
实际上是相同的,至少在与.NET 4.0捆绑在一起的Microsoft C#编译器中。
因此,在以下方法中进行比较
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
}
将编译为以下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
答案 2 :(得分:7)
Equals
方式似乎明显变慢 - 在调试模式下大约为2.7倍,在发布模式下大于7倍。
这是我快速而又肮脏的基准:
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);
}
运行它会产生以下结果:
8959
2950
1874
5348
751
7
Equals
似乎是最慢的。 ==
和!=
之间似乎没有什么区别。但是,if (!boolExpr)
似乎是明显的赢家。
答案 3 :(得分:2)
如果您反编译System.Boolean并查看它,那么定义它的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;
}
我想C#编译器的优化器和.Net JIT编译器足够聪明,可以内联这些,至少对于发布/优化的编译,使它们完全相同。
答案 4 :(得分:1)
有一个区别-至少在.NET 4.8中-我认为原因是由于Oliver Hanappi's答案中所述的拳击:
static void Main(string[] args)
{
object lhs = true;
object rhs = true;
Console.WriteLine($"Are Equal - {(lhs == rhs ? "Yes" : "No")}"); // Outputs no
Console.WriteLine($"Are Equal - {(lhs.Equals(rhs) ? "Yes" : "No")}"); // Outputs yes
Console.ReadLine();
}
答案 5 :(得分:-1)
在这种情况下,使用bools,它没有任何区别,但是对于其他内置的非引用类型,它可以。
如果==
不能,则 .Equals
允许转换类型
答案 6 :(得分:-1)
请查看以下引用Taken from here:
Equals方法只是System.Object中定义的虚拟方法 被任何一个选择这样做的课程所覆盖。 ==运算符是一个 运算符,可以通过类重载,但通常具有 身份行为。
对于尚未超载的参考类型,进行比较 两个引用是否引用同一个对象 - 这是确切的 Equals在System.Object中的实现。
简而言之,Equals
实际上只是做了==。
答案 7 :(得分:-1)
==
始终优于.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);
}
}