25
Операторы break и continue используются в циклах, первый из них
предназначен для выхода из цикла, второй – для перехода к следующей
итерации.
Обработка исключений
В этом разделе изучим, как перехватывать и обрабатывать
исключительные ситуации.
Традиционно обработка ошибок производится в теле программы, что
затрудняет понимание логики самого приложения и запутывает код.
Сообщения об ошибках представляют собой числа, которые не несут никакой
смысловой нагрузки. Более того, один и тот же код ошибки может
использоваться в разных функциях и означать совершенно разные ошибки.
В C# предусмотрен специальный механизм для генерирования и
обработки исключительных ситуаций. Все исключения – это объекты,
унаследованные от класса Exception. Названия классов раскрывают вид
исключения. Объекты могут содержать дополнительную информацию об
ошибке, например, FileNotFoundException может хранить имя файла.
Для обработки исключительной ситуации, необходимо потенциально
опасный код заключить в блок try-catch-finally. В блоке try содержится код,
который может сгенерировать исключительную ситуацию, например деление
на ноль или отсутствие запрашиваемого файла на диске. Если возникла
исключительная ситуация, выполнение кода в блоке try приостанавливается и
начинается поиск блока catch, соответствующего по типу исключительной
ситуации. Блок finally выполняется обязательно, вне зависимости от того,
произошло исключение или нет. Он используется в двух случаях: для избегания
повтора операторов и для освобождения ресурсов.
Есть несколько вариантов блока catch:
•
общий catch { ... }, что равносильно catch (System.Exception) { ... } –
обработка ошибки любого типа;
•
по виду исключения, например, catch (OutOfMemoryException caught) { ...
}, где caught – объект класса исключения OutOfMemoryException.
После блока try может присутствовать несколько блоков catch. В этом
случае у каждого блока catch необходимо явно указывать, ошибку какого типа
он обрабатывает. Нельзя чтобы в следующем блоке catch был указан тип
26
данных, наследник от класса указанном в предыдущем блоке catch. Нельзя
чтобы было два блока catch, предназначенных для обработки ошибки одного и
того же класса. Блок catch для ошибки типа System.Exception может быть
только последним.
Приведем несколько примеров.
try {
Console.WriteLine("Enter first number");
int i = int.Parse(Console.ReadLine());
Console.WriteLine("Enter second number");
int j = int.Parse(Console.ReadLine());
int k = i / j;
}
catch (OverflowException caught)
{
Console.WriteLine(caught);
}
catch(DivideByZeroException caught)
{
Console.WriteLine(caught);
}
finally
{
Console.WriteLine(“Блок try-catch завершен”);
}
Приведенный выше код не содержал никаких ошибок.
try {
...
}
catch { ... }
catch (OutOfMemoryException caught
) { ... } // ошибка – общий блок catch
следует перед блоком с конкретной ошибкой.
В следующем примере один и тот же класс используется два раза:
catch (OutOfMemoryException caught) { ... }
catch (OutOfMemoryException caught) { ... } // Error
В следующем примере сначала идет блок catch, который обрабатывает
ошибку класса Exception, в следующем блоке – ошибку класса
OutOfMemoryException
, который является наследником от класса Exception.
27
catch (Exception caught) { ... }
catch (OutOfMemoryException caught) { ... } // Error
Оператор throw генерирует исключение вручную. Можно генерировать
только объекты класса исключения, то есть для этого надо создать свой
собственный класс, наследник от класса Exception.
if (minute<1|| minute>=60){
string fault=minute + “is not a valid minute”;
throw new InvalidTimeException(fault);
…
}
В приведенном примере предполагается, что класс InvalidTimeException
описан где-то раньше, этот класс является наследником от класса Exception, его
конструктор содержит один строковый параметр.
Можно использовать оператор throw внутри блока catch:
catch (IOException caught) {
...
throw new FileNotFoundException(filename);
}
По умолчанию проверка переполнения стека арифметическими
операциями в C# выключена. Для включения проверки переполнения можно
создать блок checked, или при компиляции указать опцию: csc /checked+
example.cs
, а для отключения:
csc /checked- example.cs.
Блок unchecked явно выключает проверку. В конце
главы 3 был приведен пример для обработки исключительной ситуации,
которая возникает при переполнении арифметическими операциями.
Рекомендации по обработке исключений:
•
Включать строки описания
string description = String.Format("{0}({1}): newline in string constant",
filename, linenumber);
throw new System.Exception(description);
•
Генерировать исключения более специфичного вида, например класс
FileNotFoundException
, лучше чем более общий класс IOException.
•
Не позволять исключениям выходить из метода Main, то есть всегда
должна существовать такая конструкция
static void Main( )
{
28
try {
...
}
catch (Exception caught) {
...
}
}
Достарыңызбен бөлісу: |