Все ли типы исключений обнаруживаются под простым старым «исключением»? - PullRequest
4 голосов
/ 14 апреля 2011

Я просто пытаюсь понять это немного лучше.

Я понимаю, что существует множество различных типов исключений , и согласно некоторому прочтению, которое я сделал, все типы исключений перехватываются Исключением. Прежде всего, могу ли я быть уверен, что это правда?

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 ]

8 голосов
/ 14 апреля 2011

Это на самом деле зависит от вашей версии .NET и конфигурации.В C ++ / CLI вы можете выбросить что угодно ;это не обязательно должно быть Exception.В версии 1.1 (IIRC) вы могли поймать их только с помощью блока catch, например:

catch {...}

Что не очень полезно - вы не можете видеть, что произошло.В 2.0 (IIRC) по умолчанию такие исключения автоматически заключаются в фиктивный подкласс RuntimeWrappedException.Однако для совместимости вы можете отключить это.Я прошу вас: не :)

4 голосов
/ 14 апреля 2011

Да, это работает, потому что все стандартные исключения наследуются от Exception.

Ваш код будет работать, но вам нужно будет установить обработчик для Exception после всех специализированные типы исключений.(Первый соответствующий обработчик будет выполнен.)

Исключения, которые не наследуются от Exception, не будут перехвачены, поскольку они не являются указанным типом.Но все классы исключений .NET наследуются от этого базового класса.

Некоторые люди не думают, что это хорошая идея, но я обычно ловлю только Exception, если только я не хочу специальной обработки для определенного типа исключения.

2 голосов
/ 14 апреля 2011

Чтобы ответить на вторую часть вашего вопроса, пример иерархии исключений из .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);
    }
}
2 голосов
/ 14 апреля 2011

Да, исключение наследуется от класса Object, а все исключения наследуются от класса 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
      ...
1 голос
/ 14 апреля 2011

Да, все типы исключений наследуются от исключения.

И, как работает наследование, вы можете иметь несколько уровней наследования

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
}
1 голос
/ 14 апреля 2011

Последнее, исключения могут наследовать от базового Exception класса или любого другого класса, который наследует базовый класс.

Например: SqlException наследуется от DbException, который наследуется от ExternalException, которыйнаследуется от SystemException, который, наконец, наследуется от Exception.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...