为什么Int32.Equals(Int16)返回true而反之不返回't ?

本文关键字:返回 Equals Int32 Int16 true 为什么 | 更新日期: 2023-09-27 18:09:04

. 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
    }
}

它与我们所比较的类型的范围有关系吗?

为什么Int32.Equals(Int16)返回true而反之不返回't ?

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

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

true如果obj是Int16的一个实例并且等于this的值实例;否则,假的。

但是,我们传入的值,虽然它"等于这个实例的值"(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)

现在很明显我们调用了一个不同的等式方法。在内部,这个equals方法或多或少是这样做的:

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
}

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

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