比较两个整数对象是否相等,而不考虑类型

时间:2021-03-18 16:14:54

I'm wondering how you could compare two boxed integers (either can be signed or unsigned) to each other for equality.

我想知道如何将两个被装箱的整数(可以是有符号的,也可以是无符号的)相互比较,使它们相等。

For instance, take a look at this scenario:

例如,看看这个场景:

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

I'm stumped on how to reliably compare boxed integer types this way. I won't know what they are until runtime, and I can't just cast them both to long, because one could be a ulong. I also can't just convert them both to ulong because one could be negative.

我对如何以这种方式可靠地比较装箱整数类型感到困惑。直到运行时我才知道它们是什么,我不能把它们都转换成长时间,因为一个可能是ulong。我也不能把它们都转换成ulong因为一个可以是负的。

The best idea I could come up with is to just trial-and-error-cast until I can find a common type or can rule out that they're not equal, which isn't an ideal solution.

我能想到的最好的办法就是试错,直到我找到一个通用类型或者排除它们不相等的可能性,这不是一个理想的解决方案。

2 个解决方案

#1


35  

In case 2, you actually end up calling int.Equals(int), because ushort is implicitly convertible to int. This overload resolution is performed at compile-time. It's not available in case 3 because the compiler only knows the type of int5 and int6 as object, so it calls object.Equals(object)... and it's natural that object.Equals will return false if the types of the two objects are different.

在情形2中,您最终调用int. equals (int),因为ushort可以隐式转换为int.这个重载解析在编译时执行。在情形3中不可用,因为编译器只知道int5和int6作为对象的类型,所以它调用object. equals (object)…这个物体很自然。如果两个对象的类型不同,Equals将返回false。

You could use dynamic typing to perform the same sort of overload resolution at execution time - but you'd still have a problem if you tried something like:

您可以使用动态类型在执行时执行相同的重载解析——但是如果您尝试以下方法,您仍然会遇到问题:

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

Here there's no overload that will handle long, so it will call the normal object.Equals.

这里没有处理长数据的重载,因此它将调用normal object.Equals。

One option is to convert the values to decimal:

一种方法是将值转换为decimal:

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

This will handle comparing ulong with long as well.

这也将处理长龙的比较。

I've chosen decimal as it can exactly represent every value of every primitive integer type.

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

#2


0  

Integer is a value type. When you compare two integers types, compiller checks their values.

Integer是一种值类型。当比较两个整数类型时,compiller检查它们的值。

Object is a reference type. When you compare two objects, compiller checks their references.

对象是引用类型。当您比较两个对象时,compiller会检查它们的引用。

The interesting part is here:

有趣的是:

 object int5 = (int)50505; 

Compiller perfoms boxing operation, wraps value type into reference type, and Equals will compare references, not values.

Compiller perfoms装箱操作,将值类型包装为引用类型,并且Equals将比较引用,而不是值。

#1


35  

In case 2, you actually end up calling int.Equals(int), because ushort is implicitly convertible to int. This overload resolution is performed at compile-time. It's not available in case 3 because the compiler only knows the type of int5 and int6 as object, so it calls object.Equals(object)... and it's natural that object.Equals will return false if the types of the two objects are different.

在情形2中,您最终调用int. equals (int),因为ushort可以隐式转换为int.这个重载解析在编译时执行。在情形3中不可用,因为编译器只知道int5和int6作为对象的类型,所以它调用object. equals (object)…这个物体很自然。如果两个对象的类型不同,Equals将返回false。

You could use dynamic typing to perform the same sort of overload resolution at execution time - but you'd still have a problem if you tried something like:

您可以使用动态类型在执行时执行相同的重载解析——但是如果您尝试以下方法,您仍然会遇到问题:

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

Here there's no overload that will handle long, so it will call the normal object.Equals.

这里没有处理长数据的重载,因此它将调用normal object.Equals。

One option is to convert the values to decimal:

一种方法是将值转换为decimal:

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

This will handle comparing ulong with long as well.

这也将处理长龙的比较。

I've chosen decimal as it can exactly represent every value of every primitive integer type.

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

#2


0  

Integer is a value type. When you compare two integers types, compiller checks their values.

Integer是一种值类型。当比较两个整数类型时,compiller检查它们的值。

Object is a reference type. When you compare two objects, compiller checks their references.

对象是引用类型。当您比较两个对象时,compiller会检查它们的引用。

The interesting part is here:

有趣的是:

 object int5 = (int)50505; 

Compiller perfoms boxing operation, wraps value type into reference type, and Equals will compare references, not values.

Compiller perfoms装箱操作,将值类型包装为引用类型,并且Equals将比较引用,而不是值。