5

Using Reflector or DotPeek, the System.Linq.Data.Binary implementation of the equality operator overload looks like this:

[Serializable, DataContract]
public sealed class Binary : IEquatable<Binary>
{
...
    public static bool operator ==(Binary binary1, Binary binary2)
    {
        return ((binary1 == binary2) || (((binary1 == null) && (binary2 == null)) || (((binary1 != null) && (binary2 != null)) && binary1.EqualsTo(binary2))));
    }

I must be missing something obvious, or there is a mechanism taking place of which I'm unaware (such as implicitly calling object == within the body?). I admit, I rarely if ever need to overload standard operators.

Why does this implementation not result in an infinite recursion (which a simple test shows it doesn't recurse infinitely)? The first conditional expression is binary1 == binary2, within the implementation of the operator overload that would get called if you used binary1 == binary2 outside the implementation, and I would have thought, inside as well.

2 Answers 2

5

I expect this to be a bug in your decompiler. Redgate Reflector had/has the same bug, and I've found it in ILSpy too.

The reason why this is hard to decompile is because it subtly tests the C# overloading rules. The original code was most likely something like (object)obj1==(object)obj2, but this conversion can't be seen in the IL itself. Casting any reference type to a base type is a no-op as far as the runtime is concerned. It does however get C# to choose the referential equality opcodes instead of calling the overloaded equality operators.

IMO the correct way to implement this in a decompiler is to always decompile referential equality checks to (object)obj1==(object)obj2 and then optimize out the redundant casts if they don't affect overload resolution. This approach will fix similar problems with method overloading too.

Sign up to request clarification or add additional context in comments.

Comments

2

It is evidently a bug in your version of ReSharper (and dotpeek). Version 6.0 (6.0.2202.688) of ReSharper does it correctly:

    public static bool operator ==(Binary binary1, Binary binary2) {
        if ((object)binary1 == (object)binary2) 
            return true; 
        if ((object)binary1 == null && (object)binary2 == null)
            return true; 
        if ((object)binary1 == null || (object)binary2 == null)
            return false;
        return binary1.EqualsTo(binary2);
    } 

1 Comment

Sorry, I meant to say Reflector, not Resharper in my post (which I corrected). Interesting that the current Resharper gets it right, but DotPeek (by the same company) does not.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.