C# 抛出异常后我必须打破吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/990115/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do I have to break after throwing exception?
提问by Ross
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# 编写一个自定义类,如果人们在某些方法中提供错误的输入,我会抛出一些异常。如果抛出异常,抛出后方法中的任何代码还会被执行吗?我必须在抛出后休息一下,还是抛出总是退出方法?
采纳答案by JP Alioto
When you throwan 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 块(如果有)。您可以尝试尝试、尝试捕捉、尝试捕捉最终或尝试最终。然后,如果异常未被处理、被 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");
回答by Jarrett Widman
Throw will move up the stack, thus exiting the method.
Throw 将向上移动堆栈,从而退出该方法。
回答by SqlRyan
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
回答by BarneyHDog
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.
引发异常在资源方面是昂贵且缓慢的。如果您有许多需要应用的验证规则,那么请为这些规则编写特定的代码 - 您可能应该只依赖异常处理来处理您没有预料到的事情。
回答by chris166
I recommend stepping through your program with a debugger then you'll see for yourself what is going on. Very useful for learning!
我建议使用调试器逐步执行您的程序,然后您将亲眼看到发生了什么。对学习非常有用!
回答by Drellgor
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) throw之后方法中的任何代码都会被执行吗?
是的。如果异常在 try 中,则将执行匹配的 catch 块或 finally 块中的代码。如果没有 try 块,则否。控制分支到最近的封闭 finally,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 语句的终点不可达;编译器将抛出视为转到。紧跟在 throw 之后的语句是不可访问的,并且永远不会执行。
(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 是否总是退出方法?
不。如果 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.aspxfor details.
最后,听起来您正在抛出“笨蛋”异常,例如“嘿笨蛋来电者,我告诉过您永远不要给我这些数据”。这很棒,因为它可以防止调用者出现错误。但是如果你这样做,你应该确保调用者有某种方式知道你的期望!如果调用者无法根据您的文档确定您是否要抛出异常,那么您并没有做出愚蠢的异常,而是做出了令人烦恼的异常。有关详细信息,请参阅http://blogs.msdn.com/ericlippert/archive/2008/09/10/vexing-exceptions.aspx。