有关 C# 中异常的问题
本文关键字:问题 异常 有关 | 更新日期: 2023-09-27 17:55:33
下面是一个代码片段:
class xxx
{
public xxx(){}
try
{
throw new Exception(InvalidoperationException);
}
catch(Exception x)
{
}
catch(InvalidoperationException x)
{
}
}
谁能说出哪个例外会在这里引发,以及背后的原因是什么。
哇,这里有很多问题。从哪里开始?
-
该代码无法编译。您定义的
try-catch
块在任何方法之外,这是不允许的。您需要将其移动到方法内部。 -
永远不要抛出一个你打算稍后在方法中抓住自己的方法。这通常被称为对"流控制"使用例外,这是完全不鼓励的。这样做会产生性能成本,并且当代码引发并捕获自己的异常时,监视使用调试器时引发的异常也非常混乱。如有必要,使用布尔变量(称为标志)进行流控制。
-
始终首先捕获派生最多的异常类。这意味着您应该先抓住
InvalidOperationException
,然后再尝试抓住Exception
。您需要在拥有的代码中颠倒catch
块的顺序。 -
你几乎永远不应该抓住
System.Exception
.您应该捕获的唯一例外是您明确理解并且能够处理的例外。实际上,当您拥有的唯一信息是抛出通用异常时,您几乎无法知道出了什么问题或如何处理它。同样,您也不应该从自己的代码中抛出此异常。选择从基类
System.Exception
类继承的更具描述性的异常类,或通过从基类继承来创建自己的异常类。
我看到其他答案正在向您展示您的代码应该是什么样子的示例代码,如果它被重写。我不会这样做,因为如果我重写你的代码是正确的,我最终会得到这个:
class Xxx
{
public Xxx()
{
}
}
不是特别有用。
如果代码是这样的
class xxx
{
public xxx(){
try
{
throw new Exception(InvalidoperationException);
}
catch(InvalidoperationException x)
{
}
捕获(例外 x) { } } }
它应该编译并引发您的异常和捕获。否则,您的代码根本无法编译。
不会抛出异常,因为此代码甚至无法编译。
不管 - 几点:
- 使用异常处理时,将更具体的异常放在不太具体的异常之前(因此
InvalidOperationException
的捕获应该在Exception
的捕获之前)。 - 捕捉
Exception
通常不是很有用。 - 如果发现异常,请对其执行某些操作。
你可能的意思是:
throw new InvalidOperationException();
但是,按照您构建异常的方式,catch(Exception x)
块将运行。
你应该写:
class xxx
{
public void Test()
{
try
{
throw new InvalidoperationException();
}
catch(InvalidoperationException exception)
{
// Do smth with exception;
}
catch(Exception exception)
{
throw; // Rethrows your exception;
}
}
}
InvalidOperationException
继承自Exception
. catch
尝试处理最具体的分支,因此catch (InvalidOperationException x)
将在此处执行。
不。它不会编译。因此,毫无疑问将生成哪个异常。
你的代码应该是这样的:
class xxx
{
public void Test()
{
try
{
throw new InvalidoperationException();
}
catch(InvalidoperationException exception)
{
// Something about InvalidOperationException;
}
catch(Exception exception)
{
// Something about the Exception
}
}
}
注意事项:
- 首先编写更具体的 Exception 类,因此我们在 Exception 类之前编写 InvalidOperationException。
忽略编译问题....第一个匹配的异常块(catch(Exception x)
)将获得异常。然后你忽略异常并且不重新抛出,因此异常将被外界看到。不过,这并不能使它成为好的做法...特别是,抓住一个任意的Exception
并忽略它是有风险的——它可能是任何东西......这不一定是你认为的例外。
好吧,代码无法编译,但我只会忽略它......
如果我只看这行:
throw new Exception(InvalidoperationException);
首先,根据 MSDN 的说法,没有这样的构造函数。所以我假设你的意思是构造函数:Exception(String msg,Exception innerException)。意义: 抛出新的异常("blabla",无效操作异常);
引发的异常类型为 Exception,而不是 InvalidOperationException。所以只有捕获(例外 x)可以捕获它。
如果你抛出的 InvalidoperationException 比你编写捕获顺序的方式,则 Exception 类将首先被捕获。渔获的顺序确实很重要。
我能给你的最好的建议就是自己尝试一下,看看会发生什么。