2013-09-24 3 views
0

У меня есть следующий код в «основной» метод:Как поймать пользовательских исключений

static void Main(string[] args) 
{ 
    try 
    { 
     int a = 0; 
     int b = 5; 
     b /= a; 
    } 
    catch (MyException ex) 
    { 
     Console.WriteLine(ex.Message) 
    } 
} 

И MyException класс как:

public class MyException : Exception 
{ 
    public MyException() 
    { 

    } 
} 

Программа перерывы на b /= a; тогда я ожидая, что он перейдет к команде catch. Если я заменил MyException на Exception, исключение поймано и программа не сломается.

Как я могу поймать пользовательское исключение?

+5

Почему «b/= a» выбрасывает ваше исключение? Он выдает «System.DivideByZeroException».Если вы хотите поймать свое исключение, вы должны бросить свое исключение. Как вы думаете, что вы делаете, создавая собственное исключение? – Random832

+0

, потому что MyException унаследовано от Exception. поэтому я ожидаю, что поймаю любое исключение. – yazanpro

+0

Если DevisionByZeroException - это то, что выбрано, так как это исключение не списано в MyException, оно не попадает в catch (MyException) – Alireza

ответ

2

Как уже упоминалось в комментариях проблема заключается не в том, что вы не можете поймать исключение, проблема в том, что код не выбрасывает этот тип исключения. Он выбрасывает System.DivideByZeroException. Если вы хотите протестировать свой код, чтобы увидеть, как он поймал ваше исключение, просто замените b /= a; на throw new MyException();, и вы увидите, что он поймает ваше исключение. Он ловит что-то, когда вы используете базовый класс Exception, потому что DivicdeByZeroException также наследует от Exception.

Имейте в виду, что только ваше исключение когда-либо будет брошено, если у вас есть линия throw new MyException();. Вы можете сделать все пользовательские исключения, которые вы хотите, но библиотеки .NET не собираются просто запускать их для вас. В этом случае вы даже не должны использовать настраиваемое исключение, если это упражнение для обучения, это нормально, но на самом деле это не имеет смысла, когда у вас уже есть информативное исключение.

4

Ваш код не может поймать MyException, потому что никто не выбрасывается; Очевидно, вы не можете поймать исключение, которое не брошенную ... Этот код, однако, было бы бросить и поймать MyException:

static void Main(string[] args) 
{ 
    try 
    { 
     Foo(); 
    } 
    catch (MyException ex) 
    { 
     Console.WriteLine(ex.Message) 
    } 
} 

static void Foo() 
{ 
    throw new MyException() 
} 
2

As Random832 указывает, что линия b /= a выбрасывает System.DivideByZeroException. A DivideByZeroException не соответствует MyException.

Вы можете поймать исключение типа Exception, поскольку a DivideByZeroException распространяется Exception. Ваш MyException также распространяется на Exception, но это более производный тип Exception, который не являетсяDivideByZeroException.

1

Какая обработка исключений по существу проходит по иерархии. Для DivByZero нет обработчика, возможно, для его родителя, потом его родителя и так далее. Родитель всех исключений - это исключение, поэтому ваш код в конечном итоге улавливается. Почему это не заражает MyException, потому что нет ссылки с DivByZero на MyException. MyException находится на отдельной ветке.

0

Это как раз наоборот: если вы определяете

public class MyException : DivideByZeroException 
{ 
    public MyException() { } 
} 

и использовать

static void Main(string[] args) 
{ 
    try 
    { 
     throw new MyException(); 
    } 
    catch (DivideByZeroException ex) 
    { 
     Console.WriteLine("Exception caught"); 
    } 
} 

тогда ваш улов будет работать. catch ловит указанное вами исключение, и его потомки.

Смежные вопросы