当类型不同但兼容以比较值时,如何检查值类型的盒装对象是否相等
How to check equality of boxed object of value types when types are different but compatible to compare the values
当我们装箱两个值类型(它们是不同的类型但兼容以比较值,例如:int 和 short)并尝试调用 Equals 方法时给出 false 即使值相同。
案例一:
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
另一方面,当两个值类型相同时,等于 returns 实际值比较结果。
案例二:
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
- 如果装箱对象内的值类型不同,实际上调用了哪个 Equals 方法?
- 当装箱对象中的两个值类型相同时,如何调用该值类型的 Equals 方法?
变量的类型保存在对象中。
例如:
Console.Write(ob_a.GetType().ToString()); // will give you System.Int32
Console.Write(ob_b.GetType().ToString()); // will give you System.Int16
它也给出了不同的哈希码方法:GetHashCode()
如果您将 short 变量转换为 int 或其他方式,它将相等...所以基本上问题在于不同的变量类型。
以下是两个问题的答案: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.
当我们装箱两个值类型(它们是不同的类型但兼容以比较值,例如:int 和 short)并尝试调用 Equals 方法时给出 false 即使值相同。
案例一:
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
另一方面,当两个值类型相同时,等于 returns 实际值比较结果。
案例二:
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
- 如果装箱对象内的值类型不同,实际上调用了哪个 Equals 方法?
- 当装箱对象中的两个值类型相同时,如何调用该值类型的 Equals 方法?
变量的类型保存在对象中。
例如:
Console.Write(ob_a.GetType().ToString()); // will give you System.Int32
Console.Write(ob_b.GetType().ToString()); // will give you System.Int16
它也给出了不同的哈希码方法:GetHashCode()
如果您将 short 变量转换为 int 或其他方式,它将相等...所以基本上问题在于不同的变量类型。
以下是两个问题的答案: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.