有关 C# 中异常的问题

本文关键字:问题 异常 有关 | 更新日期: 2023-09-27 17:55:33

下面是一个代码片段:

class xxx
{
  public xxx(){}
  try
  {
    throw new Exception(InvalidoperationException);
  }
  catch(Exception x)
  {
  }
  catch(InvalidoperationException x)
  {
  }
}

谁能说出哪个例外会在这里引发,以及背后的原因是什么。

有关 C# 中异常的问题

哇,这里有很多问题。从哪里开始?

  1. 该代码无法编译。您定义的try-catch块在任何方法之外,这是不允许的。您需要将其移动到方法内部

  2. 永远不要抛出一个你打算稍后在方法中抓住自己的方法。这通常被称为对"流控制"使用例外,这是完全不鼓励的。这样做会产生性能成本,并且当代码引发并捕获自己的异常时,监视使用调试器时引发的异常也非常混乱。如有必要,使用布尔变量(称为标志)进行流控制。

  3. 始终首先捕获派生最多的异常类。这意味着您应该先抓住InvalidOperationException然后再尝试抓住Exception。您需要在拥有的代码中颠倒catch块的顺序。

  4. 你几乎永远不应该抓住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
        }
    } 
}

注意事项:

  1. 首先编写更具体的 Exception 类,因此我们在 Exception 类之前编写 InvalidOperationException。

忽略编译问题....第一个匹配的异常块(catch(Exception x))将获得异常。然后你忽略异常并且不重新抛出,因此异常将被外界看到。不过,这并不能使它成为好的做法...特别是,抓住一个任意的Exception并忽略它是有风险的——它可能是任何东西......这不一定是你认为的例外。

好吧,代码无法编译,但我只会忽略它......

如果我只看这行:

throw new Exception(InvalidoperationException);

首先,根据 MSDN 的说法,没有这样的构造函数。所以我假设你的意思是构造函数:Exception(String msg,Exception innerException)。意义: 抛出新的异常("blabla",无效操作异常);

引发的异常类型为 Exception,而不是 InvalidOperationException。所以只有捕获(例外 x)可以捕获它。

如果你抛出的 InvalidoperationException 比你编写捕获顺序的方式,则 Exception 类将首先被捕获。渔获的顺序确实很重要。

我能给你的最好的建议就是自己尝试一下,看看会发生什么。