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

但我的问题在某种程度上是不同的,我在另一种错误处理方法中调用了“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有相同的效果?


当前回答

微软文档代表:

Once an exception is thrown, part of the information it carries is the stack trace. The stack trace is a list of the method call hierarchy that starts with the method that throws the exception and ends with the method that catches the exception. If an exception is re-thrown by specifying the exception in the throw statement, the stack trace is restarted at the current method and the list of method calls between the original method that threw the exception and the current method is lost. To keep the original stack trace information with the exception, use the throw statement without specifying the exception.

来源:https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2200

其他回答

微软文档代表:

Once an exception is thrown, part of the information it carries is the stack trace. The stack trace is a list of the method call hierarchy that starts with the method that throws the exception and ends with the method that catches the exception. If an exception is re-thrown by specifying the exception in the throw statement, the stack trace is restarted at the current method and the list of method calls between the original method that threw the exception and the current method is lost. To keep the original stack trace information with the exception, use the throw statement without specifying the exception.

来源:https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2200

是的,这是有区别的。

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; } }

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

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

看这里:http://blog-mstechnology.blogspot.de/2010/06/throw-vs-throw-ex.html

把:

try 
{
    // do some operation that can fail
}
catch (Exception ex)
{
    // do some local cleanup
    throw;
}

它保留了异常堆栈信息

这叫做"重扔"

如果想要抛出新的异常,

throw new ApplicationException("operation failed!");

把交货:

try
{
    // do some operation that can fail
}
catch (Exception ex)
{
    // do some local cleanup
    throw ex;
}

它不会发送异常堆栈信息

这叫做“打破堆栈”

如果想要抛出新的异常,

throw new ApplicationException("operation failed!",ex);

为了让您从不同的角度来看待这个问题,如果您向客户端提供API,并且希望为内部库提供详细的堆栈跟踪信息,则使用throw特别有用。通过在这里使用throw,我可以获得File.Delete的System.IO.File库的堆栈跟踪。如果我使用throw ex,那么该信息将不会传递给我的处理程序。

static void Main(string[] args) {            
   Method1();            
}

static void Method1() {
    try {
        Method2();
    } catch (Exception ex) {
        Console.WriteLine("Exception in Method1");             
    }
}

static void Method2() {
    try {
        Method3();
    } catch (Exception ex) {
        Console.WriteLine("Exception in Method2");
        Console.WriteLine(ex.TargetSite);
        Console.WriteLine(ex.StackTrace);
        Console.WriteLine(ex.GetType().ToString());
    }
}

static void Method3() {
    Method4();
}

static void Method4() {
    try {
        System.IO.File.Delete("");
    } catch (Exception ex) {
        // Displays entire stack trace into the .NET 
        // or custom library to Method2() where exception handled
        // If you want to be able to get the most verbose stack trace
        // into the internals of the library you're calling
        throw;                
        // throw ex;
        // Display the stack trace from Method4() to Method2() where exception handled
    }
}