是否所有异常类型都被普通的旧“异常”所捕获?

时间:2011-04-14 18:32:13

标签: c# exception

我只是想更好地理解这一点。

我知道有很多不同的exception types,根据我已经完成的一些阅读,所有异常类型都被Exception捕获。首先,我能确定这是真的吗?

try{
    ...
}
catch(Exception x){
    //No matter what fails in the try block, x 
    //will always have a value since all exception
    //types are caught under Exception? I guess
    //What I really want to know, is will this ever
    //Fail?
}
catch(SystemException x){
    //This code will never execute since all 
    //exceptions are caught in the first catch?
}

接下来,这个捕获层次结构如何工作?如果Exception位于顶部,那么每个其他异常在Exception下是一个级别,还是有多个类型层,比如Exception是ExceptionSomething的父级,它是ExceptionSomethingElse的父级?

附录:

或者如果我们有这样的代码:

try{
    ...
}
catch(SystemException x){
    //If there is an exception that is not a SystemException
    //code in this block will not run, right (since this is 
    //looking specifically for SystemExceptions)?
}

6 个答案:

答案 0 :(得分:8)

这实际上取决于您的.NET版本和配置。在C ++ / CLI中,您可以抛出 任何 ;它不一定是Exception。在1.1(IIRC)中,你只能通过像下面这样的捕获块来捕捉这些:

catch {...}

哪个不是很有帮助 - 你看不到发生了什么。在2.0(IIRC)默认情况下这样的异常会自动包含在虚拟RuntimeWrappedException子类中。但是,为了兼容性,您可以将其关闭。求求你:不要:)。

答案 1 :(得分:4)

是的,这是有效的,因为所有标准例外都是从Exception继承的。

您的代码可以运行,但您需要在所有专用异常类型之后放置Exception的处理程序。 (第一个匹配的处理程序将执行。)

不会从Exception继承的异常将被捕获,因为它们不是指定的类型。但.NET异常类都继承自此基类。

有些人认为这不是一个好主意,但我通常只会抓住Exception,除非我想要特殊处理特定的异常类型。

答案 2 :(得分:2)

是,Exception继承自Object类,all exceptions继承自Exception类。

以上链接将显示所有例外的层次结构。

System.Object 
  System.Exception
    Microsoft.Build.BuildEngine.InternalLoggerException
    Microsoft.Build.BuildEngine.InvalidProjectFileException
    Microsoft.Build.BuildEngine.InvalidToolsetDefinitionException
    Microsoft.Build.BuildEngine.RemoteErrorException
    ...

其中一些异常,比如你提到的SystemException还有从它们继承的进一步异常,但它们仍然继承自Exception类:

System.Object 
  System.Exception
    System.SystemException
      Microsoft.SqlServer.Server.InvalidUdtException
      System.AccessViolationException
      System.Activities.ValidationException
      System.AppDomainUnloadedException
      System.ArgumentException
      System.ArithmeticException
      ...

答案 3 :(得分:2)

要回答问题的第二部分,请参阅.Net Framework中的异常层次结构示例:

ArgumentNullException inherits from
ArgumentException inherits from
SystemException  inherits from
Exception     

您应该尝试处理最具体的案例。

try{
    //something
}
catch(ArgumentNullException ex){
    //handle ArgumentNullException
}
catch(SystemException ex1)
{
    //handle other kinds of SystemException
    if(IDontWantToHandleThisExceptionHere(ex1))
    {
        throw;//  not throw new Exception(ex1);
    }
}

答案 4 :(得分:1)

后者,异常可以从基类Exception类或继承基类的任何其他类继承。

例如:SqlException继承自DbException,继承自最终继承自ExternalException的{​​{1}}的{​​{1}}。

答案 5 :(得分:1)

是的,所有异常类型都是从异常继承的。

而且,继承的工作方式,您可以拥有多级继承

MyAppException : Exception {
}

MyAppFileNotFoundException : MyAppException {
}

这通常用于具有不同类型的异常的不同行为

try {
     openfile('thisFileDoesNotExist.txt');
}
catch (MyAppFileNotFoundException ex)
{
      //warn the user the file does not exist
}
catch (Exception ex)
{
      //warn the user an unknown error occurred, log the error, etc
}