Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing operators between nullables and base types - should I?

This may well be well-known and discussed, but to my surprise I discovered today that you can give your own implementation of operators between nullables and their base types.

This means that you can have a struct which can be checked for null, and return true.

Now this would be convenient in my situation - on the advice of another member I have a struct that wraps strings. Being able to directly compare this wrapped string directly to null (rather than use a .IsNull or similar) is to me a lot more natural, and means changing from using strings to these WrappedStrings often require no other changes to the code.

But.. the fact that this feature is (I believe) little known, counter-intuitive to anyone thinking struct (which it is) over string (which it represents), and the fact that it confuses ReSharper (structValue == null warns "expression is always false") makes me think this is perhaps a dirty trick left in the dirty but neat tricks cupboard.

So I'm wondering, would you adopt it? If not, would you forgive me for doing so.. or is it really best not to go down this path?


public struct StringWrapper
{
    private readonly string str;
    public override string ToString() { return str; }

    public static bool operator ==(StringWrapper a, StringWrapper b) 
    { return a.str == b.str; }
    public static bool operator !=(StringWrapper a, StringWrapper b) 
    { return !(a == b); }
    public static bool operator ==(StringWrapper a, StringWrapper? b)
    {
        if (!b.HasValue || b.Value.str == null) return a.str == null;
        return a == (StringWrapper)b;
    }
    public static bool operator !=(StringWrapper a, StringWrapper? b) 
    { return !(a == b); }
    public static bool operator ==(StringWrapper? a, StringWrapper b) 
    { return b == a; }
    public static bool operator !=(StringWrapper? a, StringWrapper b) 
    { return !(a == b); }

    public StringWrapper(string str) { this.str = str; }
}
like image 880
Mania Avatar asked Sep 15 '11 06:09

Mania


1 Answers

I strongly believe in code that is self-documenting, and goes with the principle of least astonishment. For example, "getters" shouldn't modify data, etc. I would consider comparing a struct variable to null fairly confusing at first glance, so I would avoid it (no matter how convenient it might seem). This would be especially true if you were expecting many people to use (or at least look at) your code.

like image 195
Daniel B Avatar answered Sep 28 '22 07:09

Daniel B