我正在看关于可序列化dto的文章c# -数据传输对象。

这篇文章包含了下面这段代码:

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…这不完全等同于不处理异常吗?

结论:

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

堆栈溢出问题重新抛出无参数catch和什么都不做之间的区别?这似乎支持了我的观点,试着接球是不行的。


编辑:

只是为了给将来找到这条线索的人做个总结…

try {
    // Do stuff that might throw an exception
}
catch (Exception e) {
    throw e; // This destroys the strack trace information!
}

堆栈跟踪信息对于确定问题的根本原因至关重要!

DO

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 - try-catch (c#参考)


当前回答

在你发布的代码中的例子中,事实上,捕捉异常没有任何意义,因为在捕捉上没有做任何事情,它只是重新抛出,事实上它弊大于利,因为调用堆栈丢失了。

但是,您可以捕获异常来执行一些逻辑(例如关闭文件锁的sql连接,或者只是一些日志记录),在发生异常时将其扔回调用代码来处理。这在业务层中比在前端代码中更常见,因为您可能希望实现业务层的编码器处理异常。

在你发布的例子中,捕捉异常是没有意义的。不要那样做!

其他回答

当您为库或dll编程函数时,这可能很有用。

此重抛出结构可用于有目的地重置调用堆栈,以便从函数本身获取异常,而不是从函数内部的单个函数中查看抛出的异常。

我认为这样做只是为了让抛出的异常更清晰,并且不会进入库的“根”。

使用catch-throw的一个可能原因是禁用堆栈较深处的任何异常过滤器(随机旧链接)。当然,如果这是他们的意图,肯定会有评论这么说。

大多数答案都是关于catch-log-rethrow的。

与其在代码中编写它,不如考虑使用AOP,特别是带有OnExceptionOptions IncludeParameterValue和 IncludeThisArgument

不要这样做,

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

您将丢失堆栈跟踪信息…

无论做什么,

try { ... }
catch { throw; }

OR

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
}

这不是完全等同于不 处理异常?

不完全一样,不一样。它重置异常的堆栈跟踪。 尽管我同意这可能是一个错误,因此是一个糟糕代码的例子。