zoukankan      html  css  js  c++  java
  • throw和throw ex的区别

    之前,在使用异常捕获语句try...catch...throw语句时,一直没太留意几种用法的区别,前几天调试程序时无意中了解到几种使用方法是有区别的,网上一查,还真是,主要是区别在堆栈信息的起始点不同。总结如下:

    我们都知道,C#中使用throw和throw ex抛出异常,但二者是有区别的。

    在C#中推荐使用throw;来抛出异常;throw ex;会将到现在为止的所有信息清空,认为你catch到的异常已经被处理了,只不过处理过程中又抛出新的异常,从而找不到真正的错误源。

    throw的用法主要有以下几种:

    第一种(不推荐使用,可惜很多人都一直这么用的,包括俺,嘻嘻),这样适用会吃掉原始异常点,重置堆栈中的异常起始点:

    View Code
                try
                {
                }
                catch (Exception ex)
                {
                    throw ex;
                }

    第二种,可追溯到原始异常点,不过编译器会警告,定义的ex未有使用:

    View Code
                try
                {
                }
                catch (Exception ex)
                {
                    throw;
                }

    第三种,不带异常参数的,这个同第二种其实一样,可捕获所有类型的异常,IDE不会告警:

    View Code
                try
                {
                }
                catch
                {
                    throw;
                }

    其实第二种和第三种用法,书上也是不建议使用的,一般要从小粒度的异常捕获开始,采用多个catch语句,大家就见仁见智吧。。。

    第四种:经过对异常重新包装,但是会保留原始异常点信息。推荐使用。

    View Code
                try
                {
                }
                catch (Exception ex)
                {
                    throw new Exception("经过进一步包装的异常", ex);
                }

    下面用个例子来加以说明:

    View Code
      1         /// <summary>
      2         /// 入口方法
      3         /// </summary>
      4         public static void Main()
      5         {
      6             ExceptionClass ec = new ExceptionClass();
      7 
      8             try
      9             {
     10                 ec.ExceptionThrow1();
     11             }
     12             catch (Exception ex)
     13             {
     14                 Console.WriteLine(ex.ToString());
     15             }
     16 
     17             Console.WriteLine("---------------------------------------------------------------------");
     18 
     19             try
     20             {
     21                 ec.ExceptionThrow2();
     22             }
     23             catch (Exception ex)
     24             {
     25                 Console.WriteLine(ex.ToString());
     26             }
     27 
     28             Console.WriteLine("---------------------------------------------------------------------");
     29 
     30             try
     31             {
     32                 ec.ExceptionThrow3();
     33             }
     34             catch (Exception ex)
     35             {
     36                 Console.WriteLine(ex.ToString());
     37             }
     38 
     39             Console.WriteLine("---------------------------------------------------------------------");
     40 
     41             try
     42             {
     43                 ec.ExceptionThrow4();
     44             }
     45             catch (Exception ex)
     46             {
     47                 Console.WriteLine(ex.ToString());
     48             }
     49 
     50             Console.WriteLine("---------------------------------------------------------------------");
     51 
     52             Console.ReadKey();
     53         }
     54     }
     55 
     56     /// <summary>
     57     /// 该Class用来测试异常抛出时相关上下文栈的调用情况
     58     /// </summary>
     59     public class ExceptionClass
     60     {
     61         /// <summary>
     62         /// 抛出异常方法
     63         /// </summary>
     64         public void ExceptionThrow1()
     65         {
     66             try
     67             {
     68                 // 调用原始异常抛出方法来抛出异常
     69                 this.ExceptionMethod();
     70             }
     71             catch (Exception ex)
     72             {
     73                 throw ex;
     74             }
     75         }
     76 
     77         /// <summary>
     78         /// 抛出异常方法1
     79         /// </summary>
     80         public void ExceptionThrow2()
     81         {
     82             try
     83             {
     84                 this.ExceptionMethod();
     85             }
     86             catch (Exception ex)
     87             {
     88                 throw;
     89             }
     90         }
     91 
     92         /// <summary>
     93         /// 抛出异常方法2
     94         /// </summary>
     95         public void ExceptionThrow3()
     96         {
     97             try
     98             {
     99                 this.ExceptionMethod();
    100             }
    101             catch
    102             {
    103                 throw;
    104             }
    105         }
    106 
    107         /// <summary>
    108         /// 抛出异常方法3
    109         /// </summary>
    110         public void ExceptionThrow4()
    111         {
    112             try
    113             {
    114                 this.ExceptionMethod();
    115             }
    116             catch (Exception ex)
    117             {
    118                 throw new Exception("经过进一步包装的异常", ex);
    119             }
    120         }
    121 
    122         /// <summary>
    123         /// 原始异常抛出方法
    124         /// </summary>
    125         private void ExceptionMethod()
    126         {
    127             throw new DivideByZeroException();
    128         }
    129    }

    运行结果如下:

    从运行的结果可以看到,第一种用法已经吃掉了原始异常信息。而其它3种用法都可以追溯到原始异常,推荐使用第四种用法,希望大家能了解这些细微的差别,享受Coding的乐趣吧...

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    ddd
  • 原文地址:https://www.cnblogs.com/JerryTian/p/2699459.html
Copyright © 2011-2022 走看看