Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 为什么异常的行号指向Throw语句?_.net_Vb.net - Fatal编程技术网

.net 为什么异常的行号指向Throw语句?

.net 为什么异常的行号指向Throw语句?,.net,vb.net,.net,Vb.net,假设我有以下构造: Try Dim f As FileInfo = Nothing f.Delete() ... some other stuff... Catch ex as Exception Throw End Try 在这个简单的示例中,f.Delete将抛出NullReferenceException 为什么此异常的StackTrace中的问题行指向Throw语句,而不是f.Delete()行 如何保持Try/Catch,但将正确的堆栈跟踪指向f.Delete(

假设我有以下构造:

Try 
  Dim f As FileInfo = Nothing
  f.Delete()

  ... some other stuff...
Catch ex as Exception
   Throw
End Try
在这个简单的示例中,
f.Delete
将抛出NullReferenceException

  • 为什么此异常的StackTrace中的问题行指向
    Throw
    语句,而不是
    f.Delete()

  • 如何保持Try/Catch,但将正确的堆栈跟踪指向
    f.Delete()
    作为问题的根源

  • 一,。为什么此异常的StackTrace中的问题行指向Throw语句而不是f.Delete()行

    这取决于您正在查看的堆栈跟踪:由rethrow(catch块内的
    抛出
    生成的堆栈跟踪,还是由捕获的第一个异常生成的堆栈跟踪

    Catch ex As Exception
    行上设置断点,并使用调试器检查
    ex
    ;您将看到一个指向
    f.Delete()
    的堆栈跟踪

    Throw
    表示“重新抛出”,即原始堆栈跟踪将被保留但是,对于同一方法调用,堆栈跟踪中不会有两个条目:如果在最初导致异常的同一方法中重新抛出异常,堆栈跟踪将只包含一个指向最终重新抛出的条目。

    二,。如何保持Try/Catch,但使正确的堆栈跟踪指向f.Delete()作为问题的根源

  • 请记住,重新抛出基本上意味着“我错了,我不知道如何处理这个异常。”因此,您可以使用异常过滤器(
    Catch…When
    )来决定是否能够在捕获异常之前处理它。如果您可以在捕获它之前确定,那么应该不需要重新调用,并且不会修改堆栈跟踪

  • f.Delete()
    放在不同的方法中。这样,它在堆栈跟踪中获得自己的堆栈帧/行,并且不会被重新抛出的
  • 覆盖


    (或者,不要捕获异常只是为了重新显示它。)

    我想这也可以用来给出正确的异常(至少在“内部”异常中):


    我认为您所解释的行为是使用
    throw ex发生的情况。这就是为什么我们使用
    throw
    来推测正确的行为。我认为
    throw
    throw-ex
    之间的区别在于
    throw
    将保持原来抛出的堆栈跟踪,而
    throw-ex
    将显示从执行堆栈跟踪的行开始的堆栈跟踪。@Denis:我已经重写了我的答案。现在应该更有帮助了。所以我在做了一些测试之后现在明白了。无论您是使用
    抛出
    还是
    抛出ex
    ,这里的结果都是一样的。这两种方法都将以相同的方式覆盖此方法的堆栈帧。@Denis:在您的具体情况中可能没有区别。(另请参见和。)然而,我仍然认为原则上,
    Throw
    Throw ex
    的含义/意图不同。如果您决定无法处理异常,因此希望(尽可能)保留原始堆栈跟踪,请执行重新抛出。执行一个
    Throw ex
    在“新”抛出位置有一个异常点。不要重新抛出异常在VB.NET中很多人在方法中捕捉到异常(不管这是好的还是坏的做法)因为他们喜欢做运行时调试,如果抛出异常,它会留在函数/子函数中。他们通常通过上面的构造实现这一点,但当异常发生在代码深处时,它会导致问题,我无法确定涉及哪一行。简而言之,他们希望保留这个结构,但要使它正常工作。如果您只需要一个
    Try..Catch
    块,您可以始终使用标志来确定错误发生的位置。例如,在
    f.Delete()
    之后将整数设置为1表示成功。然后在您的
    Catch
    中,您可以测试整数,以查看您的代码是否通过了
    f.Delete()
    Try 
      Dim f As FileInfo = Nothing
      f.Delete()
    
      ... some other stuff...
    Catch ex as Exception
       Throw New Exception("Failed in Method X", ex)
    End Try