C# 是否所有异常类型都被捕获在“普通旧”下;例外情况;?

C# 是否所有异常类型都被捕获在“普通旧”下;例外情况;?,c#,exception,C#,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

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

我知道有很多不同的异常类型,根据我所做的一些阅读,所有的异常类型都被异常捕获。首先,我可以确信这是真的吗

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)?
}

是的,这是因为所有标准异常都继承自
Exception

您的代码将正常工作,但您需要将
异常的处理程序置于所有专用异常类型之后。(将执行第一个匹配的处理程序。)

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


有些人认为这不是一个好主意,但我通常只捕获异常,除非我需要对特定异常类型进行特殊处理。

是的,异常从对象类继承,并且从异常类继承

上面的链接将显示所有异常的层次结构

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
      ...

它实际上取决于您的.NET版本和配置。在C++/CLI中,您可以抛出任何东西;它不必是
异常
。在1.1(IIRC)中,您只能使用一个捕捉块捕捉这些对象,如:

catch {...}

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

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


例如:
SqlException
继承自
DbException
,它继承自
ExternalException
,它继承自
SystemException
,它最终继承自
Exception

是的,所有异常类型都继承自Exception

而且,按照继承的工作方式,您可以有多个级别的继承

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
}

要回答问题的第二部分,请举一个.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);
    }
}

如果我不添加任何抛出异常的代码,只捕获异常就足够了?@sooprise yes;在任何正常的代码中,捕捉异常都很好;但只在伐木等方面这样做;请记住
抛出
,而不是
抛出ex
重新抛出。