分类目录

链接

2012年九月
« 8月   10月 »
 12
3456789
10111213141516
17181920212223
24252627282930

近期文章

热门标签

博主推荐

现在位置:    首页 > .NET > 正文
throw和throw ex的区别
.NET 暂无评论 阅读(2,839)
throwthrow 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的乐趣吧...

本文版权归数据库之家所有,转载引用请完整注明以下信息:
本文作者:Bruce
本文地址:throw和throw ex的区别 | 数据库之家