Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform a null check in an equality operator overload

I've written a simple class that wraps an XElement. I want to pass through equality operations to the wrapped instance. So I wrote this:

public class XmlWrapper
{
    protected readonly XElement _element;

    public XmlWrapper(XElement element)
    {
        _element = element;
    }

    static public bool operator == (XmlWrapper lhs, XmlWrapper rhs)
    {
        return lhs._element.Equals(rhs._element);
    }

    static public bool operator != (XmlWrapper lhs, XmlWrapper rhs)
    {
        return !(lhs == rhs);
    }
}

This seems straightforward, but actually it throws an exception for a very simple null check:

    XmlWrapper wrapper = new XmlWrapper(someElement);
    XmlWrapper nullWrapper = null;

    if (wrapper != nullWrapper) Console.WriteLine("Wrapper is not null"); //This line throws

It's because the equality operator is receiving null for one of its arguments and therefore can't retrieve the wrapped XElement. So the obvious thought is to add a null check, like this:

static public bool operator == (XmlWrapper lhs, XmlWrapper rhs)
{
    if (lhs == null && rhs == null) return true;
    if (lhs == null || rhs == null) return false;
    return lhs._element.Equals(rhs._element);
}

However, this results infinite recursion, because the == operator calls the == operator again.

If this were any other kind of method, I'd just call the base, but that doesn't work with an operator, e.g. you can't write

if (lhs base.== rhs)

So how do I get around this? Is there some way to call the base == operator from within the overloaded operator body? Or some other way to perform the null check without using ==?

Here is the code on DotNetFiddle.

like image 990
John Wu Avatar asked Mar 03 '23 12:03

John Wu


1 Answers

public static bool operator == (XmlWrapper lhs, XmlWrapper rhs)
{
    if (Object.ReferenceEquals(lhs, null) && Object.ReferenceEquals(rhs, null))
    {
       return true;
    }

    if (Object.ReferenceEquals(lhs, null) || Object.ReferenceEquals(rhs, null))
    {
       return false;
    }

    return lhs._element.Equals(rhs._element);
}
like image 120
Chipo Hamayobe Avatar answered Mar 06 '23 16:03

Chipo Hamayobe