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

Why catch and rethrow an exception in C#?(为什么要在 C# 中捕获并重新抛出异常?)
本文介绍了为什么要在 C# 中捕获并重新抛出异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我正在看文章 C# - 数据传输对象 关于可序列化的 DTO.

I'm looking at the article C# - Data Transfer Object on serializable DTOs.

文章中包含了这段代码:

The article includes this piece of code:

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

The rest of the article looks sane and reasonable (to a noob), but that try-catch-throw throws a WtfException... Isn't this exactly equivalent to not handling exceptions at all?

尔格:

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

Or am I missing something fundamental about error handling in C#? It's pretty much the same as Java (minus checked exceptions), isn't it? ... That is, they both refined C++.

堆栈溢出问题重新抛出无参数捕获和不做任何事情之间的区别? 似乎支持我的论点,即 try-catch-throw 是无操作的.

The Stack Overflow question The difference between re-throwing parameter-less catch and not doing anything? seems to support my contention that try-catch-throw is-a no-op.

只是为以后发现这个帖子的人总结一下......

Just to summarise for anyone who finds this thread in future...

不要

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

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

The stack trace information can be crucial to identifying the root cause of the problem!

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

Catch the more specific exceptions before the less specific ones (just like Java).

参考:

  • MSDN - 异常处理
  • MSDN - try-catch(C# 参考)

推荐答案

First;文章中的代码这样做的方式是邪恶的.throw ex 会将异常中的调用堆栈重置到该 throw 语句所在的位置;丢失有关异常实际创建位置的信息.

First; the way that the code in the article does it is evil. throw ex will reset the call stack in the exception to the point where this throw statement is; losing the information about where the exception actually was created.

其次,如果你只是像这样捕获并重新抛出,我认为没有任何附加值,上面的代码示例会一样好(或者,考虑到 throw ex 位,甚至更好)没有 try-catch.

Second, if you just catch and re-throw like that, I see no added value, the code example above would be just as good (or, given the throw ex bit, even better) without the try-catch.

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

However, there are cases where you might want to catch and rethrow an exception. Logging could be one of them:

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

这篇关于为什么要在 C# 中捕获并重新抛出异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

How to know if a field is numeric in Linq To SQL(如何在 Linq To SQL 中知道字段是否为数字)
Extract sql query from LINQ expressions(从 LINQ 表达式中提取 sql 查询)
LINQ Where in collection clause(LINQ Where in collection 子句)
Orderby() not ordering numbers correctly c#(Orderby() 没有正确排序数字 c#)
Why do I get quot;error: ... must be a reference typequot; in my C# generic method?(为什么我会收到“错误:...必须是引用类型?在我的 C# 泛型方法中?)
Strange LINQ Exception (Index out of bounds)(奇怪的 LINQ 异常(索引越界))