[Tips][C#] 正确重抛例外 (Exception) 的方式

正确重抛例外 (Exception) 的方式

前言

最近在Review项目程序时,发现有把Try-Catch捕捉到之Exception直接抛出的状况(如左下图所示),其实这样是不恰当的做法;较好的方式是使用throw重抛例外就好了(如右下图所示)。这两者到底由何差异,以下将就简单实例来进行探讨。

??

差异比较

大家都知道在捕捉到例外时,可以从Exception.StackTrace属性中来获得调用栈资讯,进而了解错误发生的确切位置,以方便调试作业的进行。以下将就该资讯的完整度探讨两者之差异。

首先,先建立一个调用的推叠类做测试。当调用Aoo.DoSomethingInBoo()方法时,会依序向Boo, Coo, Doo的DoSomethingInXoo()方法执行,且最后在Doo.DoSomethingInDoo()中故意造成错误,再交由Boo.DoSomethingInBoo()捕捉此例外错误,并以 throw ex 或 throw 二次抛出例外至调用端中来比较差异。

调用端测试主程序如下,捕捉到例外错误后印出StackTrace资讯于画面上

throw ex

首先使用throw ex来抛出例外,执行看看

当我们使用 throw ex 时,会重置调用栈造成确切例外发生位置的遗失。如下图所示,错误发生点明明就在Doo.DoSomethingInDoo()中,而StackTrace提供的数据却只有到Boo.DoSomethingInBoo(),因此单就此消息无法得知实际错误到底是在哪个类方法中发生的,实在是会造成很大的困扰。

throw

接着使用throw来抛出例外,执行看看

使用throw抛出错误时,并不会重置调用栈,保有完整StackTrace资讯,方便获得例外发生点来进行调试。如下图所示,明确地指出错误发生点就在Doo.DoSomethingInDoo()中,获得完整调用栈资讯。

以下是完整的测试代码,有兴趣的朋友可以自行测试


namespace RethrowExceptionConsole
{
    class Program
    {
        static void Main(string[] args)
        {
             try
            {
                Aoo aoo = new Aoo();
                aoo.DoSomethingInAoo();
            }
            catch (Exception ex)
            {
                // display stack trace info
                Console.WriteLine( "----- stack info -----" );
                Console.WriteLine( ex.StackTrace.ToString() );
                Console.WriteLine( "----------------------" );
            }

            Console.Read();
        }
    }

    // level 1
    public class Aoo
    {
        public Boo boo = new Boo();
        public void DoSomethingInAoo()
        { boo.DoSomethingInBoo(); }
    }

    // level 2
    public class Boo
    {
        public Coo coo = new Coo();
        public void DoSomethingInBoo()
        {
            try
            {
                coo.DoSomethingInCoo();
            }
            catch (Exception ex)
            {
                // log here
                // ...

                // ## Rethrow exception ##
                // destroys the strack trace info!
                //throw ex;

                // ## Rethrow exception ##
                // preserves the stack trace
                throw;
            }
        }
    }

    // level 3
    public class Coo
    {
        public Doo doo = new Doo();
        public void DoSomethingInCoo()
        {  doo.DoSomethingInDoo(); }
    }

    // level 4
    public class Doo
    {
        public void DoSomethingInDoo()
        {
            int i = 0;
            i = 1 / i;  // cause exception
        }
    }
}


希望此篇文章可以帮助到需要的人

若内容有误或有其他建议请不吝留言给笔者喔 !

原文:大专栏  [Tips][C#] 正确重抛例外 (Exception) 的方式

原文地址:https://www.cnblogs.com/chinatrump/p/11518129.html

时间: 2024-11-06 03:38:18

[Tips][C#] 正确重抛例外 (Exception) 的方式的相关文章

在web.xml正确加载spring配置文件的方式

ssm框架整合时一直报出没有创建实例bean的错误,一直以为是代码原因,反复测试了很久,才找到原因是spring配置文件没有正确导入,下图是我的错误示例 web.xml加载spring配置文件的方式主要依据该配置文件的名称和存放的位置不同来区别,目前主要有两种方式. 1.如果spring配置文件的名称为applicationContext.xml,并且存放在WEB-INF/目录下,那么只需要在web.xml中加入以下代码即可 <listener> <listener-class>o

如何在不同场景下采用正确的重置密码和解锁方式?

就像大家知道的,ADSelfService Plus 允许员工重置忘记的密码,并且解锁自己的账户.这些功能深受大家欢迎,非常多的企业已经采取了这种模式,让员工自己去重置自己的密码.解锁他们的账户.我们要做的就是确保所有使用ADSelfService Plus的用户可以完全掌握该软件的各个功能,并能够熟练的进行操作.下面我们来讲解重置密码以及解锁账户的三种方式: 使用iPhone或者安卓手机应用程序来实现, 如图1所示.移动应用程序可以从App Store或Play Store下载.图1. ADS

正确理解springboot的常用注入方式

springboot的属性注入 以注入dataSource为例1.springboot默认读取的文件是放在resources目录下的名为application.properties或application.yml的文件在application.properties中写入以下属性jdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://127.0.0.1:3306/数据库名称jdbc.username=rootxxxjdbc.p

RuntimeException和Exception事务处理中的区别

异常的分类: ① 异常的继承结构:基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception,具体的RuntimeException继承RuntimeException. ② Error和RuntimeException及其子类成为未检查异常(unchecked),其它异常成为已检查异常(checked). runtimeException就是运行时异常,它是java编译器事先不可预见的异常.

正确使用Exception异常对象

一.异常的构成 new Exception() 创建异常对象 throw 抛出异常对象(主要性能损耗位置) try{}catch{} 捕捉异常对象 C#里面异常对象分为两个子类ApplicationException.SystemException,前者主要是提供给应用程序自定义的异常类,后者是提供给系统定义的异常类 二.如何使用异常 异常的正常逻辑是:由底层抛出,由高层处理 1.底层方法或者提供给其他人使用方法内的一些参数过滤或其它异常应该向上抛出 如(借鉴现成代码懒得写了): public

Java异常处理总结Exception\Error

Java异常处理总结Exception\Error 2012-12-28 08:17:17|  分类: JAVA |  标签:java  |举报|字号 订阅 Java异常处理总结 异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制异常痛苦,同一个异常或者错误如果多个地方出现,那么你每个地方都要做相同处理,感觉相当的麻烦! Java语言在设计的当初就考虑到这些问题,提出异常处理的框架的方案,

C#使用xsd文件验证XML 格式是否正确

方法一: 我使用XmlReader来处理,因为觉得XmlReader简单点. 我自己做了个例子来说明,例子里的XML不是很复杂,没有子节点的. XML 文件(a.xml): <?xml version="1.0" encoding="utf-8" ?> <PROFILE> <PROFILEID>0001</PROFILEID> <DESCIPTION>我的内容</DESCIPTION> <

Java中的Checked Exception——美丽世界中潜藏的恶魔?

在使用Java编写应用的时候,我们常常需要通过第三方类库来帮助我们完成所需要的功能.有时候这些类库所提供的很多API都通过throws声明了它们所可能抛出的异常.但是在查看这些API的文档时,我们却没有办法找到有关这些异常的详尽解释.在这种情况下,我们不能简单地忽略这些由throws所声明的异常: 1 public void shouldNotThrowCheckedException() { 2 // 该API调用可能抛出一个不明原因的Checked Exception 3 exception

Java 异常基础 Exception

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 1. 引子 try…catch…finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解.不过,我亲自体验的“教训”告诉我,这个东西可不是想象中的那么简单.听话.不信?那你看看下面的代码,“猜猜”它执行后的结果会是什么?不要往后看答案.也不许执行代码看真正答案哦.如果你的答案是正确,那么这篇文章你就不用浪费时间看啦. [java] view plaincopyprint? <span s