views:

59

answers:

3

Is this valid?

public struct MyStruct
{
    public int Foo { get; set; }

    public static bool operator ==(MyStruct a, MyStruct b)
    {
        return a.Equals(b);
    }

    public static bool operator !=(MyStruct a, MyStruct b)
    {
        return !a.Equals(b);
    }
}

(I know it's slightly inefficient because Object.Equals uses reflection for value types by default. But is it valid?)

I'm asking because ReSharper highlights it and warns me that MyStruct defines operator '==' or operator '!=' but does not provide 'Object.Equals(object o)' and 'Object.GetHashCode()'.

+1  A: 

Valid? Yes. But it doesn't buy you anything.

Dan Tao
It buys me the ability to compare two MyStruct instances via '==', doesn't it?
Stefan Monov
@Stefan: What, you hate typing `Equals`? ;) I meant that it doesn't buy you anything that you didn't already have (with `Equals`). Typically with a `struct` it's a good idea to actually write out the equality logic to reap the performance benefit; but it sounds like you already knew about that, based on your comment about reflection. So, if you really prefer `==` to `Equals` but understand that it's not actually giving you anything aside from that... go for it.
Dan Tao
Yes, I do prefer == to Equals because I like to treat my value types the same way as I treat primitive types. Thanks.
Stefan Monov
@Stefan: Totally reasonable. I'd still recommend overriding `Equals` to avoid the reflection overhead. But that's just me.
Dan Tao
+2  A: 

It's valid, in terms of the fact that it compiles. But it's "invalid" in the sense that it breaks all expectations of users of your class - the framework design guidelines specify that you shouldn't implement functionality that only exists in operator overloads - that such methods should be accessible in other ways. And the standard is that Object.Equals and operator== implement the same functionality.

(Can only find the 1.1 version of the guidelines at the moment):

Provide alternate signatures. Most languages do not support operator overloading. For this reason, it is a CLS requirement for all types that overload operators to include a secondary method with an appropriate domain-specific name that provides the equivalent functionality. It is a Common Language Specification (CLS) requirement to provide this secondary method. The following example is CLS-compliant.

Damien_The_Unbeliever
I believe I'm not breaking the guidelines. For my struct, Object.Equals and operator== implement the same functionality, because the latter just calls the former.
Stefan Monov
@Stefan: That is true. But ReSharper is not aware that you've "linked up" the methods in this way. I think it's just that generally, when you see that the `==` and `!=` operators have been implemented for a type, you'd expect to see `Equals` (and thus `GetHashCode`) overridden.
Dan Tao
+1  A: 

I think this may be interesting.

HCL
Thanks. The float-issue is minor, but worth knowing about.
Stefan Monov