为什么Int32.Equals(Int16)返回true,反之则不是?

时间:2015-08-20 20:25:22

标签: c# .net

.Net Equals()返回不同的结果,但我们正在比较相同的值。有人可以解释一下为什么会这样吗?

class Program
{
    static void Main(string[] args)
    {
        Int16 a = 1;
        Int32 b = 1;

        var test1 = b.Equals(a);    //true
        var test2 = a.Equals(b);    //false
    }
}

它是否必须对我们所比较的类型范围做任何事情?

2 个答案:

答案 0 :(得分:13)

Int32有一个Equals(Int32)重载,Int16可以隐含转换为等效的Int32。有了这个重载,它现在比较两个32位整数,检查值是否相等,然后自然返回true

Int16有自己的Equals(Int16)方法重载,但没有从Int32Int16的隐式转换(因为您的值可能超出范围对于16位整数)。因此,类型系统忽略此重载并恢复为Equals(Object)重载。其文件报告:

  

如果obj是Int16的实例并且等于this的值,则返回true   实例;否则,错误。

但是,我们传入的价值,而它"等于此实例的价值" (1 == 1)它的不是 Int16的实例,因为它是Int32

您拥有的b.Equals(a)的等效代码如下所示:

Int16 a = 1;
Int32 b = 1;

Int32 a_As_32Bit = a; //implicit conversion from 16-bit to 32-bit

var test1 = b.Equals(a_As_32Bit); //calls Int32.Equals(Int32)

现在很明显我们将这两个数字作为32位整数进行比较。

a.Equals(b)的等效代码如下所示:

Int16 a = 1;
Int32 b = 1;

object b_As_Object = b; //treats our 16-bit integer as a System.Object

var test2 = a.Equals(b_As_Object); //calls Int16.Equals(Object)

现在很清楚我们正在调用另一种不同的方法。在内部,这种平等方法或多或少地做了这个:

Int16 a = 1;
Int32 b = 1;

object b_As_Object = b;

bool test2;
if (b_As_Object is Int16) //but it's not, it's an Int32
{
    test2 = ((Int16)b_As_Object) == a;
}
else
{
    test2 = false; //and this is where your confusing result is returned
}

答案 1 :(得分:2)

您应该使用相等运算符(==),因为Equals()方法不应该为不同类型的对象返回true。 此外,您的代码中没有继承自shortint的类型。更改为true将返回true:

var test2 = a == b.Id;    //true