Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle operator == overload when the right hand side is of type Object

In the below example I have created a class named 'Custom' that implements IComparable:

public int CompareTo(Object value)
{
    // comparison logic here
}

Implementations of CompareTo(Object) are generally "forgiving" in that they will cast 'value' to a more specific type. In this case, a cast to the type 'Custom' will be performed so a comparison can be made. Imagine I also overload the == operator:

public static bool operator== (Custom lhs, Custom rhs)
{
    // equivalence test here
}

The problem I've run into is in this case:

Custom c = GetCustomObject();
Object o = GetOtherObject();
if(c == o)
{
     // will not be true unless c and o are the same object
}

The problem is that when == is invoked, because the rhs is of type 'Object', it falls back to the default test for reference equality - the overload is not called.

What is the expectation here? I can add another overload for the == operator:

public static bool operator== (Custom lhs, Object rhs)

But examples like this are noticeably absent from MSDN or other online examples. This makes me think that the test for reference equality is the expected behavior

like image 592
Dan Avatar asked Oct 20 '22 15:10

Dan


2 Answers

This makes me think that the test for reference equality is the expected behavior

This is correct.

It is very rarely useful to implement this in any other way, due to the fact that == is dispatched on the static type of the variables. If you implement ==(YourClass, Object) then this:

YourClass x = new YourClass();
if (x == someObject) { ... }

Will behave differently to:

Object x = new YourClass();
if (x == someObject) { ... }

This is usually unexpected!

So, if you want virtually-dispatched equality you should just use Equals.

There is only one type in System that implements an == with different argument types, and it's very special (RuntimeTypeHandle).

like image 68
porges Avatar answered Nov 01 '22 11:11

porges


(c == o) = false is totally expected. Remember, you are overloading! the operator. Your operator overload public static bool operator== (Custom lhs, Custom rhs) is not working because you don't have public static bool operator== (Custom lhs, Object rhs). Now that you have it, it makes a little sense, right?

So the solution is to use interface or base class. Comparing 2 unrelated objects doesn't make sense anyway. As you found out, .Net does it for you well already. But comparing related objects in a custom way makes perfect sense:

public static bool operator== (ICustom x, ICustom y)
like image 27
T.S. Avatar answered Nov 01 '22 11:11

T.S.