Ste*_*unn 10 c# exception-handling implicit-conversion
我们有一个具有隐式字符串运算符的类型.它看起来像这样:
public class Foo
{
readonly string _value;
Foo(string value)
{
_value = value;
}
public static implicit operator string(Foo foo)
{
return foo._value;
}
public static implicit operator Foo(string fooAsText)
{
return new Foo(fooAsText);
}
}
Run Code Online (Sandbox Code Playgroud)
我们刚刚有一个实例传递给隐式运算符null的场景.显然,我们最终得到了一个NullReferenceException.
我认为这是很公平的,毕竟,什么是一个类型,它是空的字符串表示 - 很难说 - 这样的例外似乎是有效的,这是我们不应该拦截/禁止/手柄/忽略.我的理由是'有人给我一个空的,为什么我应该返回null.我不会在其他方法中这样做.我想,'我知道,我会在转换之前检查null',类似于:
string s = foo == null ? null : foo;
但这没有用,因为它现在在比较之前转换为字符串为null.当然,这种比较可行:
Foo f = null;
string s;
if (f != null)
{
s = f;
}
Run Code Online (Sandbox Code Playgroud)
......但那只是丑陋的.
我阅读了Essential C#5第4版(Safari上的"Rough Cuts"一书)中的部分,它说:
不要从隐式转换中抛出异常.
这说不抛出异常,但它让我想知道我应该抑制异常吗?
最明显的事情是跳转到方法并将其更改为:
public static implicit operator string(Foo foo)
{
return foo == null ? null : foo._value;
}
Run Code Online (Sandbox Code Playgroud)
问题解决了.但我觉得很脏.我觉得我通过检查null隐藏了一个潜在的bug.我是偏执狂/肛门/傻瓜吗?
我想Foo表现得和一样string。所以,我期望
Foo foo = null;
string.Equals(null, foo);
Run Code Online (Sandbox Code Playgroud)
是真实的。
string.Equals 将尝试转换foo为字符串,因此它将调用隐式运算符。空值foo应该公开与空值相同的值string,即null.
因此,如果您确实想要一个隐式运算符,我会将其实现为:
public static implicit operator string(Foo foo)
{
return foo?._value;
}
Run Code Online (Sandbox Code Playgroud)