在nullables和base类型之间实现运算符 - 我应该吗?

Man*_*nia 6 c# nullable operator-overloading

这可能是众所周知和讨论的,但令我惊讶的是,我今天发现你可以在nullables和它们的基类型之间提供你自己的运算符实现.

这意味着您可以struct检查哪个null,并返回true.

现在这在我的情况下会很方便 - 在另一个成员的建议下,我有一个包裹字符串的结构.能够直接将这个包裹的字符串直接比较为null(而不是使用.IsNull或类似的)对我来说更自然,并且意味着从使用字符串转换到这些WrappedStrings通常不需要对代码进行其他更改.

但是......事实上这个特征(我相信)鲜为人知,对于任何思考结构(它都是)超过字符串(它代表)的人都是反直觉的,而且它混淆了ReSharper(structValue == null警告"表达式总是假的) ")让我觉得这可能是一个肮脏但又整洁的技巧橱柜里留下的肮脏伎俩.

所以我想知道,你会采纳它吗?如果没有,你会原谅我这样做吗?或者最好不要走这条路?


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; }
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*l B 1

我坚信代码是自我记录的,并且遵循最少惊讶的原则。例如,“getters”不应该修改数据等。乍一看,我会考虑将结构变量与 null 进行比较相当令人困惑,所以我会避免它(无论它看起来多么方便)。如果您期望很多人使用(或至少查看)您的代码,则尤其如此。