首页 > 代码库 > C#异常小知识

C#异常小知识

C#中异常捕获相信大家都很熟悉,经常使用的异常捕获有:
1. try{.....} catch (Exception ex) {throw ex;}
2. try{.....} catch (Exception) {throw;}
3. try{.....} catch (Exception ex) {throw new Exception("异常描述",ex);}
 
相信对于这3种写法大家都很熟悉,但对于这3种之间的细微区别不知大家是否清楚。今天我就给大家分享一下他们之间的区别以及哪种情况下使用哪种捕获方式比较好。
 
首先请大家看看下面这段代码:
     static void Main(string[] args)
        {
            try
            {
                Test1();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
            }
 
            Console.ReadKey();
        }
 
        static void Test1()
        {
            try
            {
                Test2();
            }
            catch (Exception ex)
            {
                //throw ex;
                //throw;
                //throw new Exception(ex.Message, ex);
            }
        }
 
        static void Test2()
        {
            throw new Exception("这儿抛出的异常");
        }
 
我们的Test2方法抛出异常,在Test1中调用,并且捕获这个异常。然后在上层main方法中调用Test1方法,捕获里面抛出来的异常。在Test1中我们分别使用3种捕获异常的方式,看看有什么不同的地方。
 
首先 try{ .....}catch (Exception ex){throw ex;}方式捕获异常:
技术分享
可以看到,在上层方法main方法中捕获的异常堆栈信息只能捕获到33行,而我们真实的异常是出现在39行的。
 
在看看try{.....} catch(Exception){throw;}方式捕获异常:
技术分享
可以看到,使用这种方法,异常堆栈信息精确的定位到了异常的产生位置39行。
 
最后在看看使用try{.....} catch(Exception ex){throw new Exception("异常描述",ex);}方式捕获异常的区别:
技术分享
可以看到,在使用这种方式捕获异常的话,上层方法main捕获的异常堆栈信息是从Test1方法开始的,也就是35行;而异常精确产生的堆栈信息是包含在InnerException 属性的对象里面的。
 
   从上面的实验可以看出:
第一种捕获异常的方法会丢失真实的异常堆栈信息。
第二种可以完整的捕获异常堆栈信息。
第三种也可以完整的捕获异常堆栈信息,还可以自定义异常描述信息。
 
综上,3种捕获方式更适合在哪种情况下使用,就明了了:
1. try{.....} catch (Exception ex) {throw ex;}  不推荐使用
2. try{.....} catch (Exception) {throw;}   在不对异常信息进行修饰或改变的时候推荐使用,也是代码段自动生成的默认方式
3. try{.....} catch (Exception ex) {throw new Exception("异常描述",ex);}   在需要对异常信息进行自定义描述的时候使用

C#异常小知识