为了账号安全,请及时绑定邮箱和手机立即绑定

为什么在C#中捕获并重新抛出异常?

为什么在C#中捕获并重新抛出异常?

C#
小唯快跑啊 2019-07-13 16:41:47
我在看那篇文章C#-数据传输对象关于可序列化的DTO。本文包括以下代码:public static string SerializeDTO(DTO dto) {     try {         XmlSerializer xmlSer = new XmlSerializer(dto.GetType());         StringWriter sWriter = new StringWriter();         xmlSer.Serialize(sWriter, dto);         return sWriter.ToString();     }     catch(Exception ex) {         throw ex;     }}这篇文章的其余部分看起来是理智和合理的(对一个菜鸟来说),但是尝试投篮会抛出一个WtfException.这不完全等同于根本不处理异常吗?因此:public static string SerializeDTO(DTO dto) {     XmlSerializer xmlSer = new XmlSerializer(dto.GetType());     StringWriter sWriter = new StringWriter();     xmlSer.Serialize(sWriter, dto);     return sWriter.ToString();}还是我忽略了C#中错误处理的一些基本内容?它和Java(减去检查异常)差不多,不是吗?也就是说,他们都改进了C+。堆栈溢出问题重投参数-少接和不做任何事之间的区别?似乎支持我的论点,尝试接球是-一个没有-操作。编辑:为了帮助那些将来发现这条线索的人.不要try {     // Do stuff that might throw an exception}catch (Exception e) {     throw e; // This destroys the strack trace information!}堆栈跟踪信息对于确定问题的根源至关重要!做try {     // Do stuff that might throw an exception}catch (SqlException e) {     // Log it     if (e.ErrorCode != NO_ROW_ERROR) { // filter out NoDataFound.         // Do special cleanup, like maybe closing the "dirty" database connection.         throw; // This preserves the stack trace     }}catch (IOException e) {     // Log it     throw;}catch (Exception e) {     // Log it     throw new DAOException("Excrement occurred", e); // wrapped & chained exceptions (just like java).}finally {     // Normal clean goes here (like closing open files).}在不太具体的异常之前捕获更具体的异常(就像Java)。参考资料:MSDN-异常处理MSDN-尝试捕获(C#引用)
查看完整描述

3 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

首先,本文中的代码所做的方式是邪恶的。throw ex将异常中的调用堆栈重置到抛出语句所在的位置;丢失有关异常实际创建位置的信息。

第二,如果您这样捕获并重新抛出,我没有看到任何附加值,上面的代码示例将同样好(或者,考虑到throw ex更好的是)没有尝试捕捉。

但是,在某些情况下,您可能希望捕获并重新抛出异常。伐木可能就是其中之一:

try {
    // code that may throw exceptions    }catch(Exception ex) {
    // add error logging here
    throw;}


查看完整回答
反对 回复 2019-07-13
?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

别这样,

try {...}catch(Exception ex){
   throw ex;}

你会失去堆栈跟踪信息.。

要么做,

try { ... }catch { throw; }

try { ... }catch (Exception ex){
    throw new Exception("My Custom Error Message", ex);}

您可能想重新抛出的原因之一是如果您处理的是不同的异常。

try{
   ...}catch(SQLException sex){
   //Do Custom Logging 
   //Don't throw exception - swallow it here}catch(OtherException oex){
   //Do something else
   throw new WrappedException("Other Exception occured");}catch{
   System.Diagnostics.Debug.WriteLine("Eeep! an error, not to worry, will be handled higher up the call stack");
   throw; //Chuck everything else back up the stack}


查看完整回答
反对 回复 2019-07-13
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

C#(在C#6之前)不支持CIL“过滤异常”,VB是这样做的,因此在C#1-5中,重新抛出异常的原因之一是在Catch()发生时没有足够的信息来确定是否真的要捕获异常。

例如,在VB中,您可以

Try
 ..Catch Ex As MyException When Ex.ErrorCode = 123
 .. End Try

.它不会处理具有不同错误代码值的MyExceptions。在V6之前的C#中,如果ErrorCode不是123,则必须捕获并重新抛出MyException:

try {
   ...}catch(MyException ex){
    if (ex.ErrorCode != 123) throw;
    ...}

因为C#6.0你可以过滤就像VB一样:

try {
  // Do stuff} catch (Exception e) when (e.ErrorCode == 123456) // filter{
  // Handle, other exceptions will be left alone and bubble up}


查看完整回答
反对 回复 2019-07-13
  • 3 回答
  • 0 关注
  • 934 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信