如果你想在一个“无null
”环境中进行编程,那么请考虑更频繁地使用扩展方法,它们不会受到NullReferenceExceptions的影响,并且至少“假装”null
已经不存在了:
public static GetExtension(this string s)
{
return (new FileInfo(s ?? "")).Extension;
}
可以被称为:
// this code will never throw, not even when somePath becomes null
string somePath = GetDataFromElseWhereCanBeNull()
textBoxExtension.Text = somePath.GetExtension()
我知道,这只是方便之举,许多人正确地认为它违反了面向对象的原则(尽管面向对象的“创始人”Bertrand Meyer认为null
是邪恶的,并完全禁止在他的面向对象设计中使用,这适用于Eiffel语言,但这是另一回事)。编辑:丹提到比尔·瓦格纳(More Effective C#)认为这是一种不良实践,他是正确的。你曾经考虑过使用IsNull
扩展方法吗?;-)
为了使您的代码更易读,另一个提示可能会有所帮助:在对象为空时更经常地使用空合并运算符来指定默认值:
WriteSettings(currentUser.Settings ?? new Settings());
public string DisplayName
{
get
{
return (currentUser ?? User.Guest).DisplayName
}
}
这些代码并没有消除对null
的偶尔检查(而??
仅仅是一个隐藏的if-分支)。我尽可能在我的代码中少用null
,因为我认为这会使代码更可读。当我的代码因为null
而凌乱不堪时,我知道设计中有问题,需要重构。我建议任何人都可以这样做,但我知道在这个问题上意见各不相同。
(更新)与异常比较
到目前为止讨论中未提到的是与异常处理的相似之处。当您发现自己在考虑某事时总是无处不在地忽略null
,它基本上就相当于写下:
try
{
//...code here...
}
catch (Exception) {}
这会导致移除任何异常的痕迹,只是在代码的后面引发不相关的异常。虽然我认为避免使用null
是好的,正如在本主题中之前提到的那样,对于异常情况来说,使用null是好的。只是不要将它们隐藏在null-ignore块中,这最终会产生与catch-all-exceptions块相同的效果。