一尘不染

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

c#

我正在看文章 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;
    }
}

本文的其余部分看起来很合理(对菜鸟而言),但是try-catch-throw引发了WtfException … 这不完全等同于根本不处理异常吗?

Ergo:

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-catch-throw是-no-op。


编辑:

总结一下,以便将来找到该线程的任何人…

不要

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)。


参考文献:


阅读 276

收藏
2020-05-19

共1个答案

一尘不染

第一; 本文中代码的执行方式是邪恶的。throw ex将异常中的调用堆栈重置到该throw语句所在的位置;丢失有关实际在何处创建异常的信息。

其次,如果您只是像这样捕获并重新抛出,我看不到有任何附加值,那么上面的代码示例如果throw ex没有try-catch
一样好(或者,如果有一点,甚至更好)。

但是,在某些情况下,您可能想捕获并重新抛出异常。日志记录可能是其中之一:

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