简体   繁体   中英

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.

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

Case 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?
  2. When both value types inside the boxed objects are same how is it calling Equals method of that value type?

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()

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.

Here is the answer for both questions: 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. Note also, that unlike a==b, expression x.Equals(y) is inherently asymmetrical. Only x dictates what version of Equals() will be called. y has absolutely no say in the matter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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