C# 为什么Int32.Equals(Int16)返回true,而反过来不返回';T

C# 为什么Int32.Equals(Int16)返回true,而反过来不返回';T,c#,.net,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 } } 它与我们

.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
有一个重载,
Int16
可以隐式转换为等价的
Int32
。通过这个重载,它现在比较两个32位整数,检查值是否相等,并自然返回
true

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

如果obj是Int16的实例且等于 实例;否则,错误

但是,我们传递的值,虽然它“等于这个实例的值”(
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
}

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

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

具有从int16到int32的隐式强制转换以及在不可能进行此类强制转换时的
对象
重载的内容。试图找到相关的Q&A…问题不是“如何使其返回true”,而是为什么
int16.Equals(int32)
不返回
true
。你是对的。但是这显示了
相等运算符
相等运算符
之间的差异。那么为什么.Net在第一种情况下进行隐式转换,
Int32.Equals(Int16)
?这是好事吗?@阿披舍克普拉喀什:是的,这通常是好事
Int32
包含了
Int16
的所有可能值,因此在需要32位整数的任何地方都可以方便地输入16位整数。32位的范围为-2147483648到2147483647,而16位的范围仅为-32768到32767。您不能做相反的操作,因为您如何将数字1000000视为16位整数?作为参考,这里是数字和转换。@AbhishekPrakash:也就是说,您当然可以通过显式转换进行反向转换(因为
1
作为32位整数仍然可以用16位表示):
Int32 a=1;int16b=(Int16)a。如果该数字符合16位大小,则在运行时这将起作用,但如果超出范围,则会抛出错误。下面是一些关于C#转换的阅读:谢谢@ChrisSinclair