一个关于c#异常的问题
以下是代码片段:
class xxx
{
public xxx(){}
try
{
throw new Exception(InvalidoperationException);
}
catch(Exception x)
{
}
catch(InvalidoperationException x)
{
}
}
任何人都可以告诉这里会引发哪个异常以及其背后的原因是什么。
following is a code snippet:
class xxx
{
public xxx(){}
try
{
throw new Exception(InvalidoperationException);
}
catch(Exception x)
{
}
catch(InvalidoperationException x)
{
}
}
can anyone tell which exception will raise here and what is the reason behind it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
哇,这里有很多问题。从哪里开始?
该代码无法编译。您定义的
try-catch
块位于任何方法之外,这是不允许的。您需要将其移动到方法的内部。永远不要抛出一个你打算稍后在该方法中自己捕获的方法。这通常被称为使用异常进行“流量控制”,这是完全不鼓励的。这样做会带来性能成本,而且当您的代码抛出并捕获它自己的异常时,使用调试器监控抛出的异常也会变得非常混乱。如有必要,请使用布尔变量(称为标志)进行流程控制。
始终首先捕获最派生的异常类。这意味着您应该在尝试捕获
Exception
之前先捕获InvalidOperationException
。您需要颠倒代码中catch
块的顺序。您实际上应该永远捕获
System.Exception
。您应该捕获的唯一异常是您明确理解并且能够处理的异常。当您拥有的唯一信息是引发了一般异常时,您几乎不可能知道出了什么问题或如何处理它。同样,您也不应该从自己的代码中抛出此异常。选择一个从
System.Exception
基类继承的更具描述性的异常类,或者通过继承该类来创建自己的异常类。我看到其他答案向您展示了示例代码,如果要重写的话,您的代码应该是什么样子。我不会这样做,因为如果我重写你的代码以使其正确,我最终会得到这样的结果:
不是特别有帮助。
Wow, lots of problems here. Where to start?
That code won't compile. The
try-catch
block that you've defined is outside of any method, which is not allowed. You need to move it inside of a method.Never throw a method that you intend to catch yourself later in the method. That's commonly known as using exceptions for "flow control", which is roundly discouraged. There is a performance cost associated with doing so, and it also makes it very confusing to monitor the exceptions that are being thrown when using a debugger when you have code that's throwing and catching it's own exceptions. Use boolean variables (known as flags) for flow control, if necessary.
Always catch the most derived exception class first. That means you should catch
InvalidOperationException
first, before trying to catchException
. You need to reverse the order of yourcatch
blocks in the code that you have.You should practically never catch
System.Exception
. The only exceptions that you should catch are those that you explicitly understand and are going to be able to handle. There's virtually no way that you're going to know what went wrong or how to handle it when the only information you have is that a generic exception was thrown.Along those same lines, you also should never throw this exception from your own code. Choose a more descriptive exception class that inherits from the base
System.Exception
class, or create your own by inheriting from the same.I see that other answers are showing you sample code of what your code should look like, were it to be rewritten. I'm not going to do that because if I rewrote your code to be correct, I'd end up with this:
Not particularly helpful.
如果代码是这样的
catch(Exception x)
{
}
}
它
应该编译并引发异常并捕获。否则你的代码根本无法编译。
If the code is like this
catch(Exception x)
{
}
}
}
It should compile and raise your exception and catch. Otherwise your code will not compile at all.
不会抛出异常,因为该代码甚至无法编译。
无论如何 - 有几点:
InvalidOperationException
的捕获应该在Exception
的捕获之前)。Exception
通常没什么用。您可能的意思是:
但是,按照您构造异常的方式,
catch(Exception x)
块将会运行。No exception will be thrown as this code will not even compile.
Regardless - several points:
InvalidOperationException
should be before the one forException
).Exception
is normally no very useful.You probably meant:
However, the way you structured your exceptions, the
catch(Exception x)
block would have run.您应该编写:
InvalidOperationException
继承自Exception
。catch
尝试处理最具体的分支,因此catch (InvalidOperationException x)
将在此处执行。You should write:
InvalidOperationException
inherits fromException
.catch
tries to processes the most specific branch, socatch (InvalidOperationException x)
will be executed here.没有。它不会编译。因此,毫无疑问会生成哪种异常。
您的代码应该是这样的:
需要注意的一点:
Nope. It wouldn't compile. So, it there's no question about as to which exception will be generated.
Your code should be something like this :
Point to be noted :
忽略编译问题....第一个匹配的异常块 (
catch(Exception x)
) 将获取异常。然后,您忽略异常并且不重新抛出,因此异常将被外界看到。不过,这并不是一个好的做法......特别是,捕获任意Exception
并忽略它是有风险的 - 它可能是任何东西......它不是不一定是您认为的例外。Ignoring the compile issue.... the first matching exception block (
catch(Exception x)
) will get the exception. You then ignore the exception and don't re-throw, so exception will be seen by the outside world. That doesn't make it good practice, though... in particular, catching an arbitraryException
and ignoring it is risky - it could have been anything... it isn't necessarily the exception you thought it was.好吧,代码不会编译,但我会忽略它......
如果我只看这一行:
首先,根据 MSDN,没有这样的构造函数。所以我假设你指的是构造函数:Exception(String msg, Exception innerException)。意义:
抛出新的异常(“blabla”,InvalidoperationException);
抛出的异常是 Exception 类型,而不是 InvalidOperationException 类型。所以 ONLY catch(Exception x) 可以捕获它。
如果您按照编写捕获顺序的方式抛出 InvalidoperationException,则 Exception 类将首先被捕获。
捕获的顺序确实很重要。
我能给你的最好建议就是自己尝试一下,看看会发生什么。
Well, the code won't compile, but I'll just ignore that...
If I'll just look at the line:
1st of all, according to MSDN there is no such constructor. So I will assume you meant the constructor: Exception(String msg, Exception innerException). Meaning:
throw new Exception("blabla", InvalidoperationException);
The exception that is being thrown is of type Exception and not InvalidOperationException. So ONLY catch(Exception x) can catch it.
If you would've thrown InvalidoperationException than the way you wrote the order of the catches, the Exception class would get caught first.
The order of the catches does matter.
The best advice I can give you is simply try it yourself and see what happens.