throw ex 和 throw 的区别

留住异常的堆栈信息【throw ex 和 throw 的区别】

 
当我们想把框架底层的异常向上抛时(比如从DAL到BLL),例如下面的代码
try
{
   
// 提交数据库
}
catch  (System.Data.SqlClient.SqlException ex)
{
   
throw  ex;
}
finally
{
   
// 释放资源
}
上面代码的的问题在于,会造成CLR重新设置异常抛出的起点,导致我们在查看异常堆栈的时候,无法知道实际抛出异常的最底层的调用。
所以上面的代码应该使用throw关键字来向上抛出异常。
 
一个完整的测试示例,诸位可以看看输出的   StackTrace   就明白,各种使用   try-catch-throw   形式的不同点了:

using   System;
using   System.Collections.Generic;
using   System.Text;

namespace   TryCatchThrowTestConsole
{
        class   Program
        {
                static   void   Main(string[]   args)
                {
                        Tester   tester   =   new   Tester();

                        System.Text.StringBuilder   sb   =   new   System.Text.StringBuilder();

                        /*
                          *   说明
                          *   1.   以下   ThrowEx_   两两成对比较
                          *   2.   ThrowEx7   和   ThrowEx8   演示已知的   throw;   与   throw   ex;   的不同,即后者   CLR   重新设置异常的起点
                          *         位于异常捕获点之上中的调用堆栈信息不会包含在   Exception   的   StackTrace   属性中
                          *   3.   ThrowEx1   和   ThrowEx2   演示本讨论的直接目标:为什么   ThrowEx2   中使用   throw;   堆栈信息也无法包括到   F2_1   这一行,而是直接到   F2_2
                          *   4.   ThrowEx3   和   ThrowEx4   情形同   ThrowEx1   和   ThrowEx2
                          *   5.   ThrowEx5   与   ThrowEx6   效果相同。
                          *   6.   try{//...}catch{throw;},   try{//...}catch(Exception){throw;},   try{//...}catch(Exception   ex){throw;}   三者是等价的
                          */

                        try   {
                                tester.ThrowEx1();
                        }
                        catch   (Exception   ex)   {
                                sb.AppendLine( "1 ");
                                sb.AppendLine(ex.StackTrace);   //   堆栈信息如期到   F1_1
                                sb.AppendLine();
                        }

                        try   {
                                tester.ThrowEx2();
                        }
                        catch   (Exception   ex)   {
                                //   堆栈信息只能到   F2_2,我的疑问是为什么不能到   F2_1
                                //   ThrowEx2()   与   ThrowEx1()   唯一区别就是   ThrowEx1()   内部还有一个   try-catch-throw                                
                                sb.AppendLine( "2 ");
                                sb.AppendLine(ex.StackTrace);  
                                sb.AppendLine();

                                //sb.AppendLine( "----------- ");
                                //sb.AppendLine(System.Environment.StackTrace);
                                //sb.AppendLine( "----------- ");

                                System.Diagnostics.StackTrace   st   =   new   System.Diagnostics.StackTrace(ex);
                                sb.AppendLine( "----------- ");
                                sb.AppendLine(st.ToString());
                                sb.AppendLine( "----------- ");
                        }

                        try   {
                                tester.ThrowEx3();
                        }
                        catch   (Exception   ex)   {
                                sb.AppendLine( "3 ");
                                sb.AppendLine(ex.StackTrace);
                                sb.AppendLine();
                        }

                        try   {
                                tester.ThrowEx4();
                        }
                        catch   (Exception   ex)   {
                                sb.AppendLine( "4 ");
                                sb.AppendLine(ex.StackTrace);
                                sb.AppendLine();
                        }

                        try   {
                                tester.ThrowEx5();
                        }
                        catch   (Exception   ex)   {
                                sb.AppendLine( "5 ");
                                sb.AppendLine(ex.StackTrace);
                                sb.AppendLine();
                        }

                        try   {
                                tester.ThrowEx6();
                        }
                        catch   (Exception   ex)   {
                                sb.AppendLine( "6 ");
                                sb.AppendLine(ex.StackTrace);
                                sb.AppendLine();
                        }

                        try   {
                                tester.ThrowEx7();
                        }
                        catch   (Exception   ex)   {
                                sb.AppendLine( "7 ");
                                sb.AppendLine(ex.StackTrace);
                                sb.AppendLine();
                        }

                        try   {
                                tester.ThrowEx8();
                        }
                        catch   (Exception   ex)   {
                                sb.AppendLine( "8 ");
                                sb.AppendLine(ex.StackTrace);
                                sb.AppendLine();
                        }

                        string   result   =   sb.ToString();
                        System.IO.File.WriteAllText( "result.txt ",   result);   //   输出到文件
                        Console.WriteLine(result);   //   输出到控制台

                        Console.Write( "press   any   key   to   exit... ");
                        Console.ReadKey();
                } 

                public   class   Tester
                {
                        public   void   ThrowEx1()
                        {
                                int   i   =   0,   j   =   0;
                                int   k   =   i   /   j;   //   F1_1
                        }

                        public   void   ThrowEx2()
                        {
                                try   {
                                        int   i   =   0,   j   =   0;
                                        int   k   =   i   /   j;   //   F2_1  
                                }
                                catch   {   //   这里   try{}catch(DivideByZeroException){throw;},   try{}catch(DivideByZeroException   ex){throw;}   等价
                                        throw;   //   F2_2
                                }                                
                        }

                        public   void   ThrowEx3()
                        {
                                throw   new   DivideByZeroException();   //   F3_1
                        }

                        public   void   ThrowEx4()
                        {
                                try   {
                                        throw   new   DivideByZeroException();   //   F4_1
                                }
                                catch   {
                                        throw;   //   F4_2
                                }
                        }

                        public   void   ThrowEx5()
                        {
                                ThrowEx1();     //   F5_1
                        }

                        public   void   ThrowEx6()
                        {
                                try   {
                                        ThrowEx1();   //   F6_1
                                }
                                catch   {
                                        throw;   //   F6_2
                                }
                        }

                        public   void   ThrowEx7()
                        {
                                try   {
                                        ThrowEx1();   //   F7_1
                                }
                                catch   (DivideByZeroException)   {   //   这里与   try{}catch{throw;},   try{}catch((DivideByZeroException   ex){throw;}   等价
                                        throw;   //   F7_2
                                }
                        }

                        public   void   ThrowEx8()
                        {
                                try   {
                                        ThrowEx1();   //   F8_1
                                }
                                catch   (DivideByZeroException   ex)   {
                                        throw   ex;   //   F8_2
                                }
                        }
                }
        }
}

转载于:https://www.cnblogs.com/simbadan/archive/2011/03/18/1988202.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值