有一些帖子问这两者之间已经有什么区别了。(为什么我要提这个…)

但我的问题在某种程度上是不同的,我在另一种错误处理方法中调用了“throw ex”。

public class Program {
    public static void Main(string[] args) {
        try {
            // something
        } catch (Exception ex) {
            HandleException(ex);
        }
    }

    private static void HandleException(Exception ex) {
        if (ex is ThreadAbortException) {
            // ignore then,
            return;
        }
        if (ex is ArgumentOutOfRangeException) { 
            // Log then,
            throw ex;
        }
        if (ex is InvalidOperationException) {
            // Show message then,
            throw ex;
        }
        // and so on.
    }
}

如果在主线中使用try和catch,那么我会使用throw;重新抛出错误。 但是在上面的简单代码中,所有异常都通过HandleException

是否抛出前任;在HandleException内部调用时,与调用throw有相同的效果?


当前回答

为了扩展Lucero的回答,下面介绍如何在不丢失原始堆栈跟踪的情况下实现原始代码的意图。

public class Program {
    public static void Main(string[] args) {
        try {
            // something
        } catch (Exception ex) {
            if (!HandleException(ex)) throw;
        }
    }

    /// <returns>
    ///   true if the exception has been handled;
    ///   false if exception should be passed along
    /// </returns>
    private static bool HandleException(Exception ex) {
        if (ex is ThreadAbortException) {
            // ignore then,
            return true;
        }
        if (ex is ArgumentOutOfRangeException) { 
            // Log then,
            return false;
        }
        if (ex is InvalidOperationException) {
            // Show message then,
            return false;
        }
        // and so on.
    }
}

其他回答

是的,这是有区别的。

throw ex resets the stack trace (so your errors would appear to originate from HandleException) throw doesn't - the original offender would be preserved. static void Main(string[] args) { try { Method2(); } catch (Exception ex) { Console.Write(ex.StackTrace.ToString()); Console.ReadKey(); } } private static void Method2() { try { Method1(); } catch (Exception ex) { //throw ex resets the stack trace Coming from Method 1 and propogates it to the caller(Main) throw ex; } } private static void Method1() { try { throw new Exception("Inside Method1"); } catch (Exception) { throw; } }

int a = 0;
try {
    int x = 4;
    int y ;
    try {
        y = x / a;
    } catch (Exception e) {
        Console.WriteLine("inner ex");
        //throw;   // Line 1
        //throw e;   // Line 2
        //throw new Exception("devide by 0");  // Line 3
    }
} catch (Exception ex) {
    Console.WriteLine(ex);
    throw ex;
}

如果所有第1、2和3行都注释了- 输出-内ex 如果所有第2行和第3行都注释了- 输出-内ex 系统。DevideByZeroException:{"试图除零。"}--------- 如果所有第1行和第2行都注释了- 输出-内ex 系统。例外:除0 ---- 如果所有第1行和第3行都注释了- 输出-内ex 系统。DevideByZeroException:{"试图除零。"}---------

和StackTrace将重置的情况下抛出ex;

不,这将导致异常具有不同的堆栈跟踪。只有在catch处理程序中使用不带任何异常对象的throw才会保持堆栈跟踪不变。

你可能想从HandleException返回一个布尔值,不管是否应该重新抛出异常。

当你抛出ex时,抛出的异常就变成了“原始”异常。因此所有之前的堆栈跟踪都不会在那里。

如果你抛出了异常,异常就会沿着这一行进行,你会得到完整的堆栈跟踪。

为了扩展Lucero的回答,下面介绍如何在不丢失原始堆栈跟踪的情况下实现原始代码的意图。

public class Program {
    public static void Main(string[] args) {
        try {
            // something
        } catch (Exception ex) {
            if (!HandleException(ex)) throw;
        }
    }

    /// <returns>
    ///   true if the exception has been handled;
    ///   false if exception should be passed along
    /// </returns>
    private static bool HandleException(Exception ex) {
        if (ex is ThreadAbortException) {
            // ignore then,
            return true;
        }
        if (ex is ArgumentOutOfRangeException) { 
            // Log then,
            return false;
        }
        if (ex is InvalidOperationException) {
            // Show message then,
            return false;
        }
        // and so on.
    }
}