C# 重试异常c情况下的StackTrace行为#

C# 重试异常c情况下的StackTrace行为#,c#,try-catch,stack-trace,throw,C#,Try Catch,Stack Trace,Throw,正如我现在已经说过的,为了保留原始的

正如我现在已经说过的,为了保留原始的
,我们应该避免使用
throw
捕获的异常,相反,我们应该只使用
throw
子句
,它实际上是
重新抛出
异常

问题是在几天前的一次采访中,我得到了一个代码来预测最终结果的
stacktrace

class Program
{
    static void Main(string[] args)
    {
        try
        {
            ReThrowException(); // line 17
        }
        catch (Exception x)
        {
            Console.WriteLine("Exception:");
            Console.WriteLine(x.StackTrace); //line 22
        }
    }

    private static void ReThrowException()
    {
        try
        {
            DivByZero(); 
        }
        catch
        {
            throw; //line 34
        }
    }

    private static void DivByZero()
    {
        int x = 0;
        int y = 1 / x; //line 41
    }
}
异常发生在
第41行
中,而在第34行,它只是通过保留原始的
堆栈跟踪
来重新显示异常

我的回答是:

它应该指向异常实际所在的
第41行
第一次发生,在中没有任何地方覆盖
stackTrace
密码

但真正的答案如下:

Exception:
   at TestConsole.Program.DivByZero() in C:...\Projects\TestConsole\TestConsole\Program.cs:line 41
   at TestConsole.Program.ReThrowException() in C:...\Projects\TestConsole\TestConsole\Program.cs:line 34
   at TestConsole.Program.Main(String[] args) in C:...\Projects\TestConsole\TestConsole\Program.cs:line 17
现在我想到两个问题:

1.为什么
stackTrace
17,34
行添加源?
2.在代码中,我应该怎么做才能将stackTrace指向
第41行并删除其他源?

“我应该怎么做才能将stackTrace指向第41行并删除其他源?”

别在34号线上接它

您应该只捕获您知道如何处理的异常。如果您曾经
catch()
catch(Exception)
那么您可能是错的(除非是为了记录日志而重新调用)

请记住,例外情况是“昂贵的”。你应该尽量避开它们。除零表示停止,如果代码的除数为零是“正常”的,那么这不是例外,应该用
if
捕获

1.stackTrace为什么要为第17、34行添加源

不是其他
,而是显示导致异常的跟踪的
堆栈
跟踪。 正如名称
StackTrace
所暗示的,它不是一个单点,同样也是一个
路径

2.我应该在代码中做些什么,使stackTrace指向第41行并删除其他源


你不能,因为你的问题来自对stackTrace存在的误解。

它没有向你显示“其他来源”。它是一个堆栈跟踪:它显示异常抛出点的调用堆栈。调用
DivByZero
的地方可能很多,堆栈跟踪显示了确切调用它的方法,以及调用该方法的方法,等等,直到应用程序的入口点(或者线程处理程序,如果它在后台线程上,等等)。它说的是“Main在第17行调用了ReThrowException;ReThrowException在第34行调用了DivByZero(除了它遇到了‘throw’点,而不是原始的方法调用);DivByZero在第41行遇到了一个问题”。你是对的,但当它指向第34行时,似乎我使用了throw ex而不是throw子句。不。如果使用
抛出ex,则会丢失指向
DivByZero
中第41行的堆栈跟踪部分<代码>抛出ex
将完全删除到目前为止记录的堆栈跟踪,然后重新开始是的,在本例中我丢失了原始文件,但它的行为就像我在第34行中抛出异常一样。不,不是--您读错了。查看第一个条目以查看引发异常的位置。其余条目显示异常“命中”的代码点,直到它最终被捕获并打印。堆栈跟踪不会显示引发异常的代码中的所有点:它会显示异常在代码中冒泡时通过的所有点。堆栈跟踪仍然会有一个
ReThrowException
条目。在这种情况下,它只会显示该条目的第30行而不是第34行