如何在类型不同但兼容比较值时检查值类型的盒装对象的相等性

时间:2017-08-08 04:35:19

标签: c# .net referenceequals

当我们设置两个值类型(不同类型但兼容比较值,例如:int和short)并尝试调用Equals方法时,即使值相同也会给出false。

案例1:

int a = 5;
short b = 5;
var ob_a = (object) a;
var ob_b = (object) b;
var result = a == b; // true
var result_for_objects = ob_a.Equals(ob_b); // false

另一方面,当两个值类型相同时,Equals返回实际值比较结果。

案例2:

int a = 5;
int b = 5;
var ob_a = (object) a;
var ob_b = (object) b;
var result = a == b; // true
var result_for_objects = ob_a.Equals(ob_b); // true

我比较了两种情况下的两个反汇编代码,但它是一样的,我找不到任何区别。

            var result = a == b;
012404DE  mov         eax,dword ptr [ebp-40h]  
012404E1  cmp         eax,dword ptr [ebp-44h]  
012404E4  sete        al  
012404E7  movzx       eax,al  
012404EA  mov         dword ptr [ebp-50h],eax  
            var result_for_objects = ob_a.Equals(ob_b);
012404ED  mov         ecx,dword ptr [ebp-48h]  
012404F0  mov         edx,dword ptr [ebp-4Ch]  
012404F3  mov         eax,dword ptr [ecx]  
012404F5  mov         eax,dword ptr [eax+28h]  
012404F8  call        dword ptr [eax+4]  
012404FB  mov         dword ptr [ebp-5Ch],eax  
012404FE  movzx       eax,byte ptr [ebp-5Ch]  
01240502  mov         dword ptr [ebp-54h],eax  
  1. 如果盒装对象内的值类型与实际调用Equals方法的值不相同?
  2. 当盒装对象内的两个值类型相同时,如何调用该值类型的Equals方法?

1 个答案:

答案 0 :(得分:4)

变量的类型保存在对象中。

例如:

Console.Write(ob_a.GetType().ToString());   // will give you System.Int32
Console.Write(ob_b.GetType().ToString());   // will give you System.Int16

它还使用方法GetHashCode()

提供不同的哈希码

如果你将短变量转换为int或其他方式,它将是相等的...所以基本上问题是不同的变量类型。

以下是两个问题的答案:http://www.ikriv.com/dev/dotnet/ObjectEquality.html

  

由于对Equals()的调用是虚拟的,因此x.Equals(y)调用的方法的精确版本由x的动态类型决定,这通常在编译时是未知的。还要注意,与a == b不同,表达式x.Equals(y)本质上是不对称的。只有x表示将调用哪个版本的Equals()。你在这件事上绝对没有发言权。