为什么要整零不等于长期零? [英] Why integer zero does not equal long zero?
问题描述
一个奇怪的一块code我刚刚发现在C#中(也应该适用于使用其他CLI语言.NET的结构
)。
A strange piece of code I've just discovered in C# (should also be true for other CLI languages using .NET's structs
).
using System;
public class Program
{
public static void Main(string[] args)
{
int a;
long b;
a = 0;
b = 0;
Console.WriteLine(a.Equals(b)); // False
Console.WriteLine(a.Equals(0L)); // False
Console.WriteLine(a.Equals((long)0)); // False
Console.WriteLine(a.Equals(0)); // True
Console.WriteLine(a.Equals(a)); // True
Console.WriteLine(a == b); // True
Console.WriteLine(a == 0L); // True
Console.WriteLine();
Console.WriteLine(b.Equals(a)); // True
Console.WriteLine(b.Equals(0)); // True
Console.WriteLine(b.Equals((int)0)); // True
Console.WriteLine(b.Equals(b)); // True
Console.WriteLine(b == a); // True
Console.WriteLine(b == 0); // True
}
}
下面两个有趣的点(假定 A
是 INT
和 B
是长
):
Two interesting points here (assuming that a
is int
and b
is long
):
-
A = B
,而B == A
;! -
(a.Equals(B))!=(A == B)
a != b
, butb == a
;(a.Equals(b)) != (a == b)
是否有任何理由,比较了这种方式实现?
Is there any reason why comparison was implemented this way?
注:.NET 4中使用,如果这有什么差别
Note: .NET 4 was used if it makes any difference.
推荐答案
在一般情况下,等于()
方法不应该返回true,针对不同类型的对象。
In general, Equals()
methods are not supposed to return true for objects of different types.
a.Equals(B)
要求 int.Equals(对象)
,只能返回true盒装的Int32
S:
a.Equals(b)
calls int.Equals(object)
, which can only return true for boxed Int32
s:
public override bool Equals(Object obj) {
if (!(obj is Int32)) {
return false;
}
return m_value == ((Int32)obj).m_value;
}
b.Equals(一)
要求 long.Equals(长)
后隐含转换 INT
到长
。
因此,它比较两个长
取值直接,返回真。
b.Equals(a)
calls long.Equals(long)
after implicitly converting the int
to a long
.
It therefore compares the two long
s directly, returning true.
要了解更清楚,看看这个简单的例子中产生的IL(它打印真假真):
To understand more clearly, look at the IL generated by this simpler example (which prints True False True):
int a = 0;
long b = 0L;
Console.WriteLine(a == b);
Console.WriteLine(a.Equals(b));
Console.WriteLine(b.Equals(a));
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: ldc.i4.0
IL_0003: conv.i8
IL_0004: stloc.1
IL_0005: ldloc.0 //Load a
IL_0006: conv.i8 //Cast to long
IL_0007: ldloc.1 //Load b
IL_0008: ceq //Native long equality check
IL_000A: call System.Console.WriteLine //True
IL_000F: ldloca.s 00 //Load the address of a to call a method on it
IL_0011: ldloc.1 //Load b
IL_0012: box System.Int64 //Box b to an Int64 Reference
IL_0017: call System.Int32.Equals
IL_001C: call System.Console.WriteLine //False
IL_0021: ldloca.s 01 //Load the address of b to call a method on it
IL_0023: ldloc.0 //Load a
IL_0024: conv.i8 //Convert a to Int64
IL_0025: call System.Int64.Equals
IL_002A: call System.Console.WriteLine //True
这篇关于为什么要整零不等于长期零?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!