haiyyu
haiyyu

Reputation: 2242

Only works when type of variable is derived class?

I have the following code:

class Program
{
    static void Main(string[] args)
    {
        Test test = new Test();
        object objTest = test;

        Console.WriteLine(test.GetType());    // Output: "OperatorOverload.Test"
        Console.WriteLine(objTest.GetType()); // Output: "OperatorOverload.Test"

        Console.WriteLine(test == null);    // Output: "True"
        Console.WriteLine(objTest == null); // Output: "False"

        test.Equals(null);    // Output: "Hi!"
        objTest.Equals(null); // Output: "Hi!"

        Console.ReadLine();
    }
}

Test looks like this:

class Test
{

    public static bool operator ==(Test obj1, Test obj2)
    {
        return true;
    }

    public static bool operator !=(Test obj1, Test obj2)
    {
        return !(obj1 == obj2);
    }

    public override bool Equals(object obj)
    {
        Console.WriteLine("Hi!");
        return true;
    }

}

It appears that operator overloading only works when the type of the variable you're dealing with is the class the operator overload is defined in. I can see why that would be the case, as I'm looking for a safe way of checking whether an object equals null.

My questions are:

Do overloaded operators only work if the type of the variable is the class the operator is defined in (my code tells me yes, but I could be making a mistake)?

Is the following code a safe way of checking whether an object equals null?

SomeClass obj = new SomeClass(); // may have overloaded operators
if ((object)obj == null)
{
    // ...
}

Upvotes: 2

Views: 162

Answers (2)

Cheng Chen
Cheng Chen

Reputation: 43531

In C# overriding overloading an operator essentially creates a static method with its name like op_xxx(e.g. op_Add, op_Equality). In your question, test == null behaviors like Test.op_Equality(test, null) which returns true obviously. While objTest == null calls Object.op_Equality(test, null) that returns false. On the other hand, you override the virtual method Equals, so test.Equals and objTest.Equals have the same result.

Upvotes: 2

Eric Lippert
Eric Lippert

Reputation: 660563

Is the following code a safe way of checking whether an object equals null?

if ((object)obj == null)

Yes. However, I personally prefer:

if (object.ReferenceEquals(obj, null))

because now it is crystal clear to the reader of the code precisely what is going on here.

You might be interested to read my article about the design factors that make Equals and operator== such odd ducks:

http://blogs.msdn.com/b/ericlippert/archive/2009/04/09/double-your-dispatch-double-your-fun.aspx

Upvotes: 5

Related Questions