为什么要整零不等于长期零? [英] Why integer zero does not equal long zero?

查看:115
本文介绍了为什么要整零不等于长期零?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个奇怪的一块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):

  1. A = B ,而 B == A ;!
  2. (a.Equals(B))!=(A == B)
  1. a != b, but b == a;
  2. (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 Int32s:

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 longs 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆