Это может быть хорошо известно и обсуждаться, но, к моему удивлению, я обнаружил сегодня, что вы можете дать свою собственную реализацию операторов между обнуляемыми значениями и их базовыми типами.
Это означает, что вы можете иметь 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; }
}