猿问

为什么在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;
    }}

这篇文章的其余部分看起来是理智和合理的(对一个菜鸟来说),但是尝试投篮会抛出一个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)。


参考资料:


小唯快跑啊
浏览 935回答 3
3回答

弑天下

首先,本文中的代码所做的方式是邪恶的。throw ex将异常中的调用堆栈重置到抛出语句所在的位置;丢失有关异常实际创建位置的信息。第二,如果您这样捕获并重新抛出,我没有看到任何附加值,上面的代码示例将同样好(或者,考虑到throw ex更好的是)没有尝试捕捉。但是,在某些情况下,您可能希望捕获并重新抛出异常。伐木可能就是其中之一:try {     // code that may throw exceptions    }catch(Exception ex) {     // add error logging here     throw;}

慕桂英4014372

别这样,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}

小怪兽爱吃肉

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}
随时随地看视频慕课网APP
我要回答