抛出异常后我是否必须休息?

时间:2023-01-10 00:03:32

I'm writing a custom class in C# and I'm throwing a couple exceptions if people give the wrong inputs in some of the methods. If the exception is thrown, will any of the code in the method after the throw still be executed? Do I have to put a break after the throw, or does a throw always quit the method?

我正在用C#编写一个自定义类,如果人们在某些方法中给出错误的输入,我会抛出几个例外。如果抛出异常,抛出后方法中的任何代码仍会被执行吗?我必须在投掷后休息一下,还是投掷总是退出方法?

6 个解决方案

#1


30  

When you throw an exception, the next code to get executed is any catch block that covers that throw within the method (if any) then, the finally block (if any). You can have a try, a try-catch, a try-catch-finally or a try-finally. Then, if the exception is not handled, re-thrown by a catch block or not caught at all, control is returned to the caller. For example, you will get "Yes1, Yes2, Yes3" from this code ...

当你抛出异常时,下一个要执行的代码是任何catch块,它覆盖方法中的抛出(如果有的话),finally块(如果有的话)。你可以尝试一下try-catch,try-catch-finally或者try-finally。然后,如果未处理异常,由catch块重新抛出或根本没有捕获,则将控制权返回给调用者。例如,您将从此代码中获得“Yes1,Yes2,Yes3”...

try
{
    Console.WriteLine("Yes1");
    throw (new Exception());
    Console.WriteLine("No1");

}
catch
{
    Console.WriteLine("Yes2");
    throw;
    Console.WriteLine("No2");
}
finally
{
    Console.WriteLine("Yes3");
}

Console.WriteLine("No3");

#2


27  

Throw will move up the stack, thus exiting the method.

投掷将向上移动,从而退出该方法。

#3


3  

I recommend stepping through your program with a debugger then you'll see for yourself what is going on. Very useful for learning!

我建议您使用调试器逐步执行程序,然后您将自己查看正在发生的事情。学习非常有用!

#4


2  

I came here looking for an answer to the original post and almost missed a very valuable answer posted by Eric Lippert. Here's his answer posted in the comments:

我来到这里寻找原帖的答案,几乎错过了Eric Lippert发布​​的非常有价值的答案。以下是他在评论中发表的答案:

Split this up into three questions.

将其分为三个问题。

(1) Will any of the code in the method after the throw be executed?
YES. If the exception was inside a try then code inside matching catch blocks or finally block will be executed. If there is no try block then NO. Control branches to the nearest enclosing finally, catch or (in vb) exception filter block up the stack.

(1)抛出后方法中的任何代码都会被执行吗?是。如果异常在try中,则匹配catch块或finally块内的代码将被执行。如果没有尝试阻止则NO。控制分支到最近的封闭最后,catch或(在vb中)异常过滤器阻塞堆栈。

(2) Do I have to put a break after the throw?
NO, never do that. The end point of the throw statement is not reachable; a throw is treated as a goto by the compiler. A statement immediately following a throw is not reachable and will never execute.

(2)投掷后我是否需要休息一下?不,永远不要那样做。 throw语句的结束点无法访问;抛出被编译器视为goto。抛出后立即发出的语句无法访问,永远不会执行。

(3) Does a throw always quit the method?
NO. If the throw is in a try and the try has a matching catch block then the catch block can "eat" the exception. Only if there is no catch block does the exception do a non-local goto up the call stack.

(3)投掷总是退出方法吗?没有。如果throw是try并且try有一个匹配的catch块,那么catch块可以“吃掉”异常。只有在没有catch块的情况下,异常才会在调用堆栈中执行非本地操作。

If you have more questions about this, I recommend reading the C# specification; all this behavior is clearly documented.

如果您对此有更多疑问,我建议您阅读C#规范;所有这些行为都有明确的记录。

Finally, it sounds like you are throwing "boneheaded" exceptions, as in "hey boneheaded caller, I told you to never give me that data". That's great because it prevents bugs in callers. But if you do that, you should make sure that the caller has some way of knowing what you expect! If the caller cannot figure out whether you're going to throw or not based on your documentation, then you haven't made a boneheaded exception, you've made a vexing exception. See http://blogs.msdn.com/ericlippert/archive/2008/09/10/vexing-exceptions.aspx for details.

最后,听起来你正在抛出“愚蠢”的例外情况,就像“嘿嘿啰嗦的来电者,我告诉过你永远不要给我那些数据”。这很好,因为它可以防止来电者的错误。但是如果你这样做,你应该确保调用者有某种方式知道你的期望!如果调用者无法根据你的文档弄清楚你是否会抛出,那么你还没有做出一个愚蠢的例外,你已经做了一个令人烦恼的例外。有关详细信息,请参见http://blogs.msdn.com/ericlippert/archive/2008/09/10/vexing-exceptions.aspx。

#5


1  

If you've wrapped your code in a Try...Catch...Finally block, then the code under Finally will always execute. For example:

如果您已将代码包装在Try ... Catch ... Finally块中,则Finally下的代码将始终执行。例如:

Try
  ' do some stuff here
  ' Examine user input
  If user input isn't valid
      Throw new exception
Catch
   Throw ' Just re-throws the same exception
Finally
   ' This code will execute, no matter what - exception or not
End Try

#6


1  

As an aside to your actual question: you might want to rethink using exceptions to provide validation info back to the user.

除了您的实际问题之外:您可能希望重新考虑使用异常向用户提供验证信息。

Raising exceptions is expensive resource-wise and slow. If you have a number of validation rules that you need to apply then write specific code for these - you should probably only rely on exception handling for things you don't anticipate.

提高异常在资源方面是昂贵且缓慢的。如果您需要应用许多验证规则,那么请为这些规则编写特定代码 - 您应该只依赖异常处理来处理您未预料到的事情。

#1


30  

When you throw an exception, the next code to get executed is any catch block that covers that throw within the method (if any) then, the finally block (if any). You can have a try, a try-catch, a try-catch-finally or a try-finally. Then, if the exception is not handled, re-thrown by a catch block or not caught at all, control is returned to the caller. For example, you will get "Yes1, Yes2, Yes3" from this code ...

当你抛出异常时,下一个要执行的代码是任何catch块,它覆盖方法中的抛出(如果有的话),finally块(如果有的话)。你可以尝试一下try-catch,try-catch-finally或者try-finally。然后,如果未处理异常,由catch块重新抛出或根本没有捕获,则将控制权返回给调用者。例如,您将从此代码中获得“Yes1,Yes2,Yes3”...

try
{
    Console.WriteLine("Yes1");
    throw (new Exception());
    Console.WriteLine("No1");

}
catch
{
    Console.WriteLine("Yes2");
    throw;
    Console.WriteLine("No2");
}
finally
{
    Console.WriteLine("Yes3");
}

Console.WriteLine("No3");

#2


27  

Throw will move up the stack, thus exiting the method.

投掷将向上移动,从而退出该方法。

#3


3  

I recommend stepping through your program with a debugger then you'll see for yourself what is going on. Very useful for learning!

我建议您使用调试器逐步执行程序,然后您将自己查看正在发生的事情。学习非常有用!

#4


2  

I came here looking for an answer to the original post and almost missed a very valuable answer posted by Eric Lippert. Here's his answer posted in the comments:

我来到这里寻找原帖的答案,几乎错过了Eric Lippert发布​​的非常有价值的答案。以下是他在评论中发表的答案:

Split this up into three questions.

将其分为三个问题。

(1) Will any of the code in the method after the throw be executed?
YES. If the exception was inside a try then code inside matching catch blocks or finally block will be executed. If there is no try block then NO. Control branches to the nearest enclosing finally, catch or (in vb) exception filter block up the stack.

(1)抛出后方法中的任何代码都会被执行吗?是。如果异常在try中,则匹配catch块或finally块内的代码将被执行。如果没有尝试阻止则NO。控制分支到最近的封闭最后,catch或(在vb中)异常过滤器阻塞堆栈。

(2) Do I have to put a break after the throw?
NO, never do that. The end point of the throw statement is not reachable; a throw is treated as a goto by the compiler. A statement immediately following a throw is not reachable and will never execute.

(2)投掷后我是否需要休息一下?不,永远不要那样做。 throw语句的结束点无法访问;抛出被编译器视为goto。抛出后立即发出的语句无法访问,永远不会执行。

(3) Does a throw always quit the method?
NO. If the throw is in a try and the try has a matching catch block then the catch block can "eat" the exception. Only if there is no catch block does the exception do a non-local goto up the call stack.

(3)投掷总是退出方法吗?没有。如果throw是try并且try有一个匹配的catch块,那么catch块可以“吃掉”异常。只有在没有catch块的情况下,异常才会在调用堆栈中执行非本地操作。

If you have more questions about this, I recommend reading the C# specification; all this behavior is clearly documented.

如果您对此有更多疑问,我建议您阅读C#规范;所有这些行为都有明确的记录。

Finally, it sounds like you are throwing "boneheaded" exceptions, as in "hey boneheaded caller, I told you to never give me that data". That's great because it prevents bugs in callers. But if you do that, you should make sure that the caller has some way of knowing what you expect! If the caller cannot figure out whether you're going to throw or not based on your documentation, then you haven't made a boneheaded exception, you've made a vexing exception. See http://blogs.msdn.com/ericlippert/archive/2008/09/10/vexing-exceptions.aspx for details.

最后,听起来你正在抛出“愚蠢”的例外情况,就像“嘿嘿啰嗦的来电者,我告诉过你永远不要给我那些数据”。这很好,因为它可以防止来电者的错误。但是如果你这样做,你应该确保调用者有某种方式知道你的期望!如果调用者无法根据你的文档弄清楚你是否会抛出,那么你还没有做出一个愚蠢的例外,你已经做了一个令人烦恼的例外。有关详细信息,请参见http://blogs.msdn.com/ericlippert/archive/2008/09/10/vexing-exceptions.aspx。

#5


1  

If you've wrapped your code in a Try...Catch...Finally block, then the code under Finally will always execute. For example:

如果您已将代码包装在Try ... Catch ... Finally块中,则Finally下的代码将始终执行。例如:

Try
  ' do some stuff here
  ' Examine user input
  If user input isn't valid
      Throw new exception
Catch
   Throw ' Just re-throws the same exception
Finally
   ' This code will execute, no matter what - exception or not
End Try

#6


1  

As an aside to your actual question: you might want to rethink using exceptions to provide validation info back to the user.

除了您的实际问题之外:您可能希望重新考虑使用异常向用户提供验证信息。

Raising exceptions is expensive resource-wise and slow. If you have a number of validation rules that you need to apply then write specific code for these - you should probably only rely on exception handling for things you don't anticipate.

提高异常在资源方面是昂贵且缓慢的。如果您需要应用许多验证规则,那么请为这些规则编写特定代码 - 您应该只依赖异常处理来处理您未预料到的事情。