Реализация операторов между обнуляемыми и базовыми типами - я должен? - PullRequest
6 голосов
/ 15 сентября 2011

Это может быть хорошо известно и обсуждаться, но, к моему удивлению, я обнаружил сегодня, что вы можете дать свою собственную реализацию операторов между обнуляемыми значениями и их базовыми типами.

Это означает, что вы можете иметь struct, который можно проверить на null, и вернуть true .

Теперь это будет удобно в моей ситуации - по совету другого члена У меня есть структура, которая переносит строки. Возможность напрямую сравнивать эту обернутую строку с нулем (а не использовать .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; }
}

1 Ответ

1 голос
/ 23 сентября 2011

Я твердо верю в код, который самодокументируется и соответствует принципу наименьшего удивления . Например, «геттеры» не должны изменять данные и т. Д. Я бы посоветовал сравнить структурную переменную с нулевой, что на первый взгляд сбивает с толку, поэтому я бы ее избегал (как бы удобно это ни казалось). Это было бы особенно верно, если бы вы ожидали, что многие люди будут использовать (или хотя бы смотреть) ваш код.

...