c# – 异常处理实践

前端之家收集整理的这篇文章主要介绍了c# – 异常处理实践前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
无论如何,我有点混淆什么时候传播异常,什么时候包装,和差异.

目前,我的理解告诉我,包装异常将涉及到像DriveNotFound(在IO中)的异常,然后用一般的IOException包装它.

但是,传播一个异常的概念,只有当我有一个空的catch子句时才会发生这种情况吗?所以在ASP.NET网络应用程序中,它将传播到global.asax.或者在最近部署的Web应用程序的情况下,未处理的HTTPException给出了一个黄色的死亡屏幕,并将一个日志写入Windows Server(这是一个我正在重写的Web应用程序).所以异常发生在一个方法中,它可以在类级别处理,显示页面中,然后升级到global.asax或Windows Server.

为什么我要用更通用的方法来包装异常?规则是处理最具体类型的异常(因此DriveNotFound显然是未找到的驱动器).另外,如何在包装和替换异常之间进行选择?

异常处理链只是try和catch(或catch)的子句?我从这个措辞来看,是的.

最后,为什么以及如何让异常传播到callstack?

我已经阅读了关于异常处理的MS PandP指南,但是我猜这些例子并没有让我充分了解一切.

这个问题来自于企业库的包装/传播异常等的能力.我不知道传播的方式,以及替换/包装异常的差异.

另外,是否可以将复杂的错误处理逻辑插入到catch块中(例如ifs / elses和类似的东西).

谢谢

解决方法

不少于6个问题:-)

But with the concept of propagating an exception,is this only something that happens if I have an empty catch clause?

异常将向上传播,直到被捕获块进一步捕获到处理特定异常类型的调用堆栈或更接近异常层次结构的基本类型的异常类型.所以,例如,所有托管异常都来自于System.Exception,所以拦截System.Exception的catch块将捕获每个受管异常.

Why exactly do I want to wrap an exception with a more generic one?

我不知道你的意思是“包装”.您是否意味着捕获异常,将其替换为另一个异常,并将原始代码添加为新异常的InnerException属性?或者是其他东西?

我认为很少有一个很好的理由用更通用的异常来替换异常.但是,您可以将异常替换为另一个例外,其中一个或多个原因有三个:

从主叫方隐藏实现细节.
>提高抽象级别,使其对调用者更有意义.
抛出一个非常具体的问题的自定义异常.

Also,how would I choose between wrapping and replacing an exception?

我很抱歉,但我仍然不明白你如何将这两个定义为不同的.

Is the exception handling chain just the try and catch (or catches) clauses?

以下是抛出异常时会发生什么的基础知识:

> CLR沿着本地Try … End Try块中的Catch块列表顺序排列,寻找具有与引发的异常匹配的异常过滤器的本地Catch块.
>如果本地Catch块具有与抛出的确切异常相匹配的异常过滤器,则该Catch块中的代码将被执行,后面是Finally块中的代码.然后在End Try之后的第一个语句继续执行.
>或者,如果抛出的异常从本地Catch块指定的异常派生,则相同的操作如第二步所述.例如,捕获ArgumentException的异常过滤器也将捕获从ArgumentException派生的异常,例如ArgumentNullException,InvalidEnumArgumentException,DuplicateWaitObjectException和ArgumentOutOfRangeException.
>如果没有本地的Catch块与引发的异常匹配,CLR将通过方法来追溯调用堆栈方法,寻找一个想要响应异常的Catch块.如果在调用堆栈中找不到匹配的Catch块,则异常被认为是未处理的.
>或者,如果在调用堆栈中找到匹配的Catch块,则执行throw和catch之间的每个Finally块中的代码.这最后属于Try块,其中抛出异常,并在最后的方法下面完成了异常捕获的方法.
>对于捕获异常的所有方法完成此清理后,控制将转移到捕获异常的捕获块,并执行此代码.运行之后的是Try被捕获的Try的finally块.现在调用堆栈已经解卷并且错误清理已经完成,最后一步是在End尝试捕获异常的第一个语句之后继续执行.
>如果Catch块中的代码导致另外的异常被抛出,原始异常将使用InnerException属性自动附加到新异常.以这种方式,可以堆叠异常,而不会丢失任何信息.
>您应该避免将清理代码放在可能引发异常的Finally块中,除非该代码在其自己的Try块中.没有这种增加的保护,CLR的行为就像在Finally块结束之后抛出新的异常,并查找要响应新异常的远程Catch块的调用堆栈.原始的例外将会丢失,除非原来的Catch块保存.

Finally,why and how would I want to let an exception propagate up the callstack?

为什么:每当你不明白异常并知道如何从中恢复时,你应该让它向上传播.

如何:只捕获您了解并知道如何处理的异常类型.有时您需要任何异常的详细信息才能正确恢复.在这种情况下,你可以抓住它,做恢复,然后使用throw重新抛出;声明.

Also,is it ok to insert complex error handling logic in a catch block (e.g. ifs/elses and things like that).

通常是的,因为您的Catch块中的代码引起的任何新异常都将通过InnerException属性自动附加旧的异常.但是如果你能避免这个机制,那么引发这个机制是不明智的,所以你拥有的更简单的代码越好.保持Catch代码简单的另一个好原因是它通常不会经历与您的主线代码相同程度的测试.

猜你在找的C#相关文章