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.
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.
In case 2, you actually end up calling
int.Equals(int)
, becauseushort
is implicitly convertible toint
. This overload resolution is performed at compile-time. It's not available in case 3 because the compiler only knows the type ofint5
andint6
asobject
, so it callsobject.Equals(object)
... and it's natural thatobject.Equals
will returnfalse
if the types of the two objects are different.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:
Here there's no overload that will handle
long
, so it will call the normalobject.Equals
.One option is to convert the values to
decimal
:This will handle comparing
ulong
withlong
as well.I've chosen
decimal
as it can exactly represent every value of every primitive integer type.Integer is a value type. When you compare two integers types, compiller checks their values.
Object is a reference type. When you compare two objects, compiller checks their references.
The interesting part is here:
Compiller perfoms boxing operation, wraps value type into reference type, and
Equals
will compare references, not values.