在可空值和基本类型之间实现运算符 - 我应该吗?
这可能是众所周知的并且被讨论过,但令我惊讶的是,我今天发现您可以在可空值及其基本类型之间提供您自己的运算符实现。
这意味着您可以拥有一个可以检查 null
的 struct
,并返回 true。
现在,这在我的情况下会很方便 - 根据 另一个成员 我有一个包装字符串的结构。能够直接将此包装字符串直接与 null 进行比较(而不是使用 .IsNull 或类似的)对我来说更加自然,并且意味着从使用字符串更改为这些 WrappedString 通常不需要对代码进行其他更改。
但是..事实上,这个功能(我相信)鲜为人知,对于任何认为结构(它是)而不是字符串(它代表)的人来说都是违反直觉的,而且它使 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; }
}
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; }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我坚信代码是自我记录的,并且遵循最少惊讶原则。例如,“getters”不应该修改数据等。乍一看,我会考虑将结构变量与 null 进行比较相当令人困惑,所以我会避免它(无论它看起来多么方便)。如果您期望很多人使用(或至少查看)您的代码,则尤其如此。
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.