.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
}
}
它是否必须对我们所比较的类型范围做任何事情?
答案 0 :(得分:13)
Int32
有一个Equals(Int32)
重载,Int16
可以隐含转换为等效的Int32
。有了这个重载,它现在比较两个32位整数,检查值是否相等,然后自然返回true
。
Int16
有自己的Equals(Int16)
方法重载,但没有从Int32
到Int16
的隐式转换(因为您的值可能超出范围对于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。
此外,您的代码中没有继承自short
和int
的类型。更改为true将返回true:
var test2 = a == b.Id; //true