简体   繁体   English

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

[英]How to check equality of boxed object of value types when types are different but compatible to compare the values

When we box two value types(which are different types but compatible to compare the values eg: int and short) and try to call Equals method on that gives false even the values are same. 当我们将两个值类型(它们是不同类型但可以比较以比较值,例如:int和short)装箱并尝试调用Equals方法时,即使值相同,也会给出false。

Case 1: 情况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

On the other hand when the both value types are same the Equals returns the actual value comparison result. 另一方面,当两个值类型相同时,Equals返回实际值比较结果。

Case 2: 情况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

I compared the both disassembly code for of both case but it was same, I was not able to find any difference. 我比较了这两种情况的两种反汇编代码,但都一样,我找不到任何区别。

            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. If value types inside the boxed objects are not same which Equals method is actually getting called? 如果装箱对象内部的值类型不同,实际上是哪个Equals方法被调用?
  2. When both value types inside the boxed objects are same how is it calling Equals method of that value type? 当装箱对象内的两个值类型相同时,如何调用该值类型的Equals方法?

The type of the variable is kept in object. 变量的类型保留在对象中。

For example: 例如:

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

It gives different hash codes also with method: GetHashCode() 它也使用方法提供不同的哈希码: GetHashCode()

If you will convert short variable to int or the other way, it will be equal... So basically the problem is with different variable types. 如果将short变量转换为int或以其他方式转换,则将是相等的...因此,基本上,问题出在不同的变量类型上。

Here is the answer for both questions: http://www.ikriv.com/dev/dotnet/ObjectEquality.html 这是两个问题的答案: http : //www.ikriv.com/dev/dotnet/ObjectEquality.html

Since call to Equals() is virtual, exact version of the method that will be called by x.Equals(y) is determined by dynamic type of x, that usually is not known at compile time. 由于对Equals()的调用是虚拟的,因此将由x.Equals(y)调用的方法的确切版本由x的动态类型确定,通常在编译时未知。 Note also, that unlike a==b, expression x.Equals(y) is inherently asymmetrical. 还要注意,与a == b不同,表达式x.Equals(y)本质上是不对称的。 Only x dictates what version of Equals() will be called. 只有x指示将调用哪个版本的Equals()。 y has absolutely no say in the matter. 您对此事绝对没有发言权。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM