Нужно явно выбросить исключение в C #? - PullRequest
1 голос
/ 04 июля 2019

Требуется ли явно генерировать исключение в блоке try? Что произойдет, если я не сгенерирую исключение в блоке try?

try
{
    // code that throws an exception
    throw new IndexOutofRangeException;
}
catch (IndexOutOfRangeException ex)    
{
   Console.WriteLine(ex.Message);
}

РЕДАКТИРОВАТЬ : В частности, представьте себе, что в блоке try есть код, который генерирует исключение, но блок try не имеет throw заявление. Что будет?

Ответы [ 3 ]

2 голосов
/ 04 июля 2019

Что произойдет, если я не сгенерирую исключение в блоке try?

Если вы не сгенерируете исключение, и никакое другое исключение не возникает, блок catchне побежитВместо этого код пропустит блок catch и продолжит выполнение всего, что будет потом (включая блок finally, если он есть).

представьте, что в блоке try есть код, которыйгенерирует исключение, но блок try не имеет оператора throw.

Блок catch будет по-прежнему выполняться ... тогда и только тогда, когда тип исключения соответствует типу, объявленномуcatch блок.Давайте посмотрим на несколько примеров.Сначала приведем пример:

try
{
   double x = 1 / 0.0;
}
catch (DivideByZeroException ex)
{
    Console.WriteLine(ex.Message);
} 

В этом случае у нас есть код, вызывающий исключение DivideByZeroException.Поскольку это соответствует типу, используемому в блоке catch, будет запущен обработчик исключений.

Далее:

try
{
   double x = 1 / 0.0;
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
} 

У нас все еще есть исключение DivideByZeroException ... но так какDivideByZeroException унаследовано от базового типа Exception, все по-прежнему совместимо, и блок catch будет запущен.

Еще один:

try
{
   double x = 1 / 0.0;
}
catch (InvalidOperationException ex)
{
    Console.WriteLine(ex.Message);
} 

У нас все еще есть исключение DivideByZeroException,но на этот раз catch блок не совместим.В этом случае программа будет аварийно завершать работу из-за необработанного исключения (если только это исключение не обработано где-либо еще в стеке программы).

Еще одно:

try
{
   double x = 1 / 0.0;
}
catch (InvalidOperationException ex)
{
    Console.WriteLine(ex.Message);
} 
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

Два catch блоков!Первый блок не будет работать, потому что он не совместим с типом DivideByZeroException.Тем не менее, второй блок catch будет работать, потому что он совместим.Исключение обрабатывается, и программа может продолжаться.

Наконец:

double DbyZ(double numerator)
{
    try 
    {
        return numerator / 0.0;
    }
    catch(InvalidOperationException ex)
    {
        Console.WriteLine("Invalid operation");
    }
} 

...

try
{
     DbyZ(1.0);
}
catch(Exception ex)
{
    Console.WriteLine("Exception");
}

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

Если у вас все еще есть вопросы о том, что может произойти в конкретном случае, создайте свои собственные образцы для тестирования случая исм.

2 голосов
/ 04 июля 2019

OP:

throw new IndexOutofRangeException;

Это не даже компилируется (без скобок).

Вы должны генерировать исключения, если что-то неожиданно в вашем домене, и вы должны ловить их там, где вы знаете, как обрабатывать их.

Вы писали:

«В блоке try есть код, который генерирует исключение, но у блока try нет оператора throw. Что произойдет?».

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

0 голосов
/ 04 июля 2019

Если код создает исключение, но не выдает его, try / catch не видит его.Создание исключения - единственное, что отличает исключение от любого другого типа класса.

.NET исключения являются программными артефактами.Хотя многие из них соответствуют аппаратным перехватам или ошибкам ОС, они не создают, не генерируют и не генерируют объекты исключений .NET.Что происходит, так это то, что другие ошибки обнаруживаются кодом в механизме выполнения .NET, который затем создает и выбрасывает объект исключения .NET, переводя информацию об ошибках нижнего уровня в свойства исключения .NET.

Этот код перевода / переноса может быть вызван на основе событий, например, путем установки обработчика для обработки структурированных исключений Windows, вместо того, чтобы иметь код для проверки каждого арифметического результата для NaN с плавающей запятой.Но это все еще программное обеспечение.В качестве конкретного примера, в ответе Джоэла код 1 / 0.0 не генерирует DivideByZeroException.Он генерирует исключение FPU, и общеязыковая среда выполнения обрабатывает это исключение FPU.Именно обработчик в CLR создает и выбрасывает экземпляр DivideByZeroException, который попадает в ваш блок catch.

...