无论类型如何,比较两个整数对象是否相等
Compare two integer objects for equality regardless of type
我想知道如何比较两个盒装整数(可以有符号或无符号)是否相等。
例如,看看这个场景:
// 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
因为一个可能是负数。
我能想到的最好的办法就是反复试错,直到我找到一个共同的类型或者可以排除它们不相等,这不是一个理想的解决方案。
在情况 2 中,您实际上最终调用了 int.Equals(int)
,因为 ushort
可以隐式转换为 int
。此重载决议在 compile-time 处执行。它在情况 3 中不可用,因为编译器只知道 int5
和 int6
的类型为 object
,所以它调用 object.Equals(object)
... 很自然 object.Equals
将 return 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);
这也将处理 ulong
与 long
的比较。
我选择了decimal
,因为它可以准确地表示每个原始整数类型的每个值。
整数是 value 类型。当您比较两个整数类型时,编译器会检查它们的 values.
对象是 reference 类型。当您比较两个对象时,编译器会检查它们的 references.
有趣的部分在这里:
object int5 = (int)50505;
编译器执行 boxing 操作,将值类型包装成引用类型,Equals
将比较引用,而不是值。
我想知道如何比较两个盒装整数(可以有符号或无符号)是否相等。
例如,看看这个场景:
// 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
因为一个可能是负数。
我能想到的最好的办法就是反复试错,直到我找到一个共同的类型或者可以排除它们不相等,这不是一个理想的解决方案。
在情况 2 中,您实际上最终调用了 int.Equals(int)
,因为 ushort
可以隐式转换为 int
。此重载决议在 compile-time 处执行。它在情况 3 中不可用,因为编译器只知道 int5
和 int6
的类型为 object
,所以它调用 object.Equals(object)
... 很自然 object.Equals
将 return 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);
这也将处理 ulong
与 long
的比较。
我选择了decimal
,因为它可以准确地表示每个原始整数类型的每个值。
整数是 value 类型。当您比较两个整数类型时,编译器会检查它们的 values.
对象是 reference 类型。当您比较两个对象时,编译器会检查它们的 references.
有趣的部分在这里:
object int5 = (int)50505;
编译器执行 boxing 操作,将值类型包装成引用类型,Equals
将比较引用,而不是值。