Exception handling 这是一个空的try-catch的有效原因,还是有更优雅的解决方案?
假设我有以下类层次结构: Person对象包含Customer对象,Customer对象包含Address对象 我不在乎客户是否有地址,但如果他们有,我想将其保存到数据库中。那么在这种情况下,有这样的东西是不是很好:Exception handling 这是一个空的try-catch的有效原因,还是有更优雅的解决方案?,exception-handling,Exception Handling,假设我有以下类层次结构: Person对象包含Customer对象,Customer对象包含Address对象 我不在乎客户是否有地址,但如果他们有,我想将其保存到数据库中。那么在这种情况下,有这样的东西是不是很好: try { Address addr = person.Customer.Address; db.SaveAddress(addr); } catch { //I don't care, but if it is there, just save it.
try
{
Address addr = person.Customer.Address;
db.SaveAddress(addr);
}
catch
{
//I don't care, but if it is there, just save it.
}
在上面,我不在乎客户是空的还是地址是空的。我的另一个选择是
if(person.Customer != null)
{
if(person.Customer.Address != null)
{
}
}
但是,如果层次结构很长,则上述内容可能很长。有没有更优雅的方法来检查对象链是否为空,而不必检查每个对象。对于异常情况,您应该始终使用异常。由于CPU上会出现一些上下文切换,您将遭受性能损失 您可以将第二个示例与大多数短路语言组合成一行
if(person.Customer != null && person.Customer.Address != null)
{
}
例如:
bool isAddressValid = person.Customer != null && person.Customer.Address != null;
if (isAddressIsValid) { }
上下文切换:对于异常情况,应始终使用异常。由于CPU上会出现一些上下文切换,您将遭受性能损失 您可以将第二个示例与大多数短路语言组合成一行
if(person.Customer != null && person.Customer.Address != null)
{
}
例如:
bool isAddressValid = person.Customer != null && person.Customer.Address != null;
if (isAddressIsValid) { }
上下文切换:如果您知道可能发生这种情况,并且可以避免异常,那么您应该始终检查
null
(或任何情况),原因是异常很慢,并且正如您所指出的,不雅。只需使用:
if(person.Customer != null && person.Customer.Address != null) {
// ...
}
如果您知道可能发生异常,并且可以避免异常,则应始终检查
null
(或任何情况),原因是异常速度慢,并且正如您所指出的,不美观。只需使用:
if(person.Customer != null && person.Customer.Address != null) {
// ...
}
对普通控制流使用异常是非常糟糕的做法。由于堆栈展开,try-catch变量可能比null检查慢1000倍。对普通控制流使用异常是一种非常糟糕的做法。由于堆栈展开,try-catch变体的速度可能比null检查慢1000倍。这是异常的一个非常糟糕的用法。有时会出现“可疑”和“鬼鬼祟祟”的地方,但这完全是错误的。。。糟糕 这是不好的,因为您掩盖了其中所有可能的异常,并且没有向代码中添加关于可能掩盖的内容的自我文档 如果
SavePerson
无法保存此人怎么办(一切都会很愉快地继续下去(好吧,除了没有得救的弗雷德先生……他可能会难过。)
带有显式“null check”的代码没有这个问题,它添加了自我文档。很明显,预期会出现null
情况(该推理是否有效是另一回事)如果压痕级别的数量是问题,考虑内部方法,不接受“代码> NULL/<代码>值的合同。< /P>
愉快的编码。这是一个非常糟糕的异常用法。有时会出现“可疑”和“鬼鬼祟祟”的地方,但这完全是……糟糕
这是不好的,因为您掩盖了其中所有可能的异常,并且没有向代码中添加关于可能掩盖的内容的自我文档
如果SavePerson
救不了这个人怎么办?:(一切都会很愉快地继续下去(好吧,除了没有得救的弗雷德先生……他可能会心烦意乱。)
带有显式“null check”的代码没有这个问题,它添加了自我文档。很明显,预期会出现null
情况(该推理是否有效是另一回事)如果压痕级别的数量是问题,考虑内部方法,不接受“代码> NULL/<代码>值的合同。< /P>
愉快的编码。让代码检查条件,而不是捕获任何异常并忽略它,有几个原因。首先想到的两个原因是:
OutOfMemoryException
保存,您会捕获并忽略它。在您的情况下,即使您尝试捕获并忽略一个异常,也最好只捕获NullReferenceException
,而忽略其余异常。更好的做法是定义您自己的异常类型(例如,CustomerHasNoAddressException
)并仅捕获该异常让代码检查条件,而不是捕获任何异常并忽略它,有几个原因。首先想到的两个原因是:
OutOfMemoryException
保存,您会捕获并忽略它。在您的情况下,即使您尝试捕获并忽略一个异常,也最好只捕获NullReferenceException
,而忽略其余异常。更好的做法是定义您自己的异常类型(例如,customerhasnoaddress)