2016-01-26 92 views
28

我想知道如何比较两个盒装整数(可以是有符号或无符号)彼此是否相等。比较两个整数对象是否相等,无论类型

例如,看看这个场景:

// case #1 
object int1 = (int)50505; 
object int2 = (int)50505; 
bool success12 = int1.Equals(int2); // this is true. (pass) 

// case #2 
int int3 = (int)50505; 
ushort int4 = (ushort)50505; 
bool success34 = int3.Equals(int4); // this is also true. (pass) 

// case #3 
object int5 = (int)50505; 
object int6 = (ushort)50505; 
bool success56 = int5.Equals(int6); // this is false. (fail) 

我难倒就如何可靠地比较盒装整型这种方式。直到运行时我才会知道它们是什么,我不能将它们都投到long,因为其中一个可能是ulong。我也不能将它们都转换为ulong,因为可能是负面的。

我可以想出的最好的想法是只是试错法,直到找到一个常见的类型或者可以排除它们不相等,这不是一个理想的解决方案。

+1

'int3.Equals()'是不是真正的被覆盖的'Equals',它的过载('等于(INT)''VS等于(对象)') – Rob

+0

你的意思 “但情况3失败”? –

+0

[((object)(int)1).Equals(((object(ushort)1))yield false?](http:// stackoverflow。com/questions/25305393/why-does-objectint1-equalsobjectushort1-yield-false) –

回答

35

在第二种情况下,你实际上最终调用int.Equals(int),因为ushort隐式转换为int。这个重载解析在编译时执行。它在情况3中不可用,因为编译器只知道int5int6的类型为object,所以它调用object.Equals(object) ...并且如果两个对象的类型不同,那么object.Equals将返回false是自然的。

可能使用动态类型在执行时执行相同类型的重载的 - 但你仍然有一个问题,如果你尝试过这样的:

dynamic x = 10; 
dynamic y = (long) 10; 
Console.WriteLine(x.Equals(y)); // False 

这里没有重载会处理long,所以它会调用正常object.Equals

一种选择是将值转换为decimal

object x = (int) 10; 
object y = (long) 10; 
decimal xd = Convert.ToDecimal(x); 
decimal yd = Convert.ToDecimal(y); 
Console.WriteLine(xd == yd); 

这将处理比较ulonglong为好。

我选择了decimal,因为它可以准确地表示每个基本整数类型的每个值。

0

整数是value类型。当你比较两种整数类型时,compiller检查它们的

对象是reference类型。当你比较两个物体时,compiller检查他们的参考文献

有趣的部分是在这里:

object int5 = (int)50505; 

Compiller同名但boxing操作,包装值类型为引用类型,并Equals会比较参考,并不值。

+1

问题中的措辞应该清楚,我知道价值和参考类型之间的差异,但实际上这根本不回答问题。 – caesay