最好检测异常并抛出它们,或者让运行时抛出它们
本文关键字:或者 运行时 异常 检测 | 更新日期: 2023-09-27 18:29:40
假设有这样的设置:
public class MyClass
{
public void DoSomething(string Data)
{
//if (String.IsNullOrWhiteSpace(Data))
//throw new NullReferenceException();
//Do something with Data and let it throw??
}
}
public class EntryPointClass
{
public void DoIt(string Data)
{
var logicClass = new MyClass();
try
{
logicClass.DoSomething(Data);
}
catch(Exception ex)
{
}
}
}
在DoSomething中,我可以检测到问题并引发异常。在测试EntryPointClass时,我可以测试预期的结果,或者测试catch中发生了什么。
为什么抛出异常比等待异常发生要好?不管怎样,我们都抓住了!
两者兼而有之:
public void DoSomething(string Data)
{
if (String.IsNullOrWhiteSpace(Data))
//throw new NullReferenceException();
throw new ArgumentException("Data");
//Do something with Data and let it throw??
}
目的是尽早投掷并提供具体信息
扔到这里的直接原因是与DoSomething()
的合同被破坏了。发出信号,不要等待`DoSomething()继续执行并破坏其他合同。
快失败,早失败。
抛出自己的异常,以防止外部看到异常的实际来源,从而获得有关实现的信息。
您可以将参数异常与自定义消息或自定义异常一起抛出,以提供有关参数无效原因的更多详细信息。
使用Exception处理的目的是处理可能超出您控制范围的异常。如果您计划将代码包装在try-catch块中(NullReferenceException除外),那么您应该准备好一些东西来处理这种类型的异常,并执行与此错误相关的任何必要操作。
也就是说,在你知道自己可能会出现引发异常的错误的情况下,最好检查一下这种情况——不要抛出错误,而是优雅地处理它。否则,你只是根据异常进行编码,这是一种反模式。
请记住,异常正是您的规则的异常,而不是在代码执行过程中可能出错的所有异常。
把例外想象成一个从着火的房子里跳出来并大声呼救的人:你不想让他们吓到普通民众,但你确实希望他们通知合适的人对火灾采取行动。考虑到这一点:
1) 如果你在DoSomething中有问题,并且你知道如何修复它——你不需要异常:只需在DoSomething中修复它。
2) 如果DoSomething在处理问题时遇到问题(属性错误、资源不可用等)-请使用异常来ESCALATE问题,并在可能的级别上进行处理。
3) 如果DoSomething以一种你无法以任何方式影响的方式被搞砸了(比如到处都是文件系统崩溃和IO异常)——只需捕捉一个异常,记录它并优雅地关闭——至少这种情况看起来不会像内爆。
在一组情况下,不应该尝试提前检测错误情况,而不仅仅是让代码失败,即存在对代码控制之外的外部资源的依赖。例如,任何与网络、文件系统等有关的东西。
其中任何一个的问题都是,检查代码可以成功,然后实际操作仍然会失败。添加检查代码所做的一切都会增加您编写的代码量-无论如何,您仍然必须编写代码来处理实际故障。
Eric Lippert有一篇关于Exception的精彩文章。
请点击链接。它是关于如何处理异常的非常好的资源。
根据经验,尽量避免出现异常,而不是试图处理异常。不要抓住所有的例外。我在您的代码中看到Catch(Exception ex)
。捕获可以处理的异常。当你得到OutofMemoryException
、ThreadAbortException
时,你无能为力
我同意Henk Holterman
。