Тема 11. Обработка исключительных ситуаций
Классические типы контроля ошибок
Возврат значения функцией
Значение, возвращаемое функцией может сигнализировать о том, была ли ошибка и если была, то какая.
class Program
{
static int WriteDiv(int a, int b)
{
if (b == 0)
return -1; // Ошибка
Console.WriteLine( a / b );
return 0; // Ок
}
static void Main(string[] args)
{
int x = 7;
int y = 0;
int Err = WriteDiv( x, y );
if ( Err != 0 ) // Ошибка ?
Console.WriteLine("Error");
}
}
Контроль переменной «флажка ошибки» после операции
Состояние того, была ли ошибка и если была, то какая может быть определено глобальной переменной.
class Program
{
static int Err;
static int WriteDiv(int a, int b)
{
int Result = 0;
if (b == 0)
Err = -1;
else
{
Err = 0;
Result = a / b;
}
return Result;
}
static void Main(string[] args)
{
int x = 7;
int y = 0;
int Res = WriteDiv(x, y);
if (Err != 0)
Console.WriteLine("Error");
else
Console.WriteLine( Res );
}
}
Исключительные ситуации ( Exception )
При проектировании сложных систем, состоящих из компонентов имеющих слабые связи ( например один компонент разработан на одном языке программирования, другой на другом ) использование глобальной переменной затруднительно. Использование возвращаемого функцией значения ограничивает использование функций, ведь функция часто должна возвращать что-то полезное ( например sin, cos, ... ).
Механизм управления исключительными ситуациями свободен от этих недостатков.
Пример: Функция записывает в БД возраст клиента компании с проверкой на диапазон значений от 18 лет до 60 лет. Является ли ввод 65 лет ошибкой ? В современном программировании это не ошибка, а нестандартная ситуация - исключительная ситуация Exception.
class Program
{
static void WriteDiv(int a, int b)
{
if (b == 0)
throw new Exception("Divider cannot be zero.");
Console.WriteLine(a / b);
}
static void Main(string[] args)
{
int x = 7;
int y = 0;
try
{
WriteDiv(x, y);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Продвижение исключительной ситуации
При возникновении исключительной ситуации внутри одной из функций произойдет выход из функции и последующие операции не сработают. При выходе из функции Main произойдет выход из программы.
class Program
{
static int P1()
{
int x = 7;
int y = 0;
int r = x / y; // Исключительная ситуация + выход из функции
Console.WriteLine("P1 done."); // Инструкция не сработает
return r; // Инструкция не сработает
}
static int P2()
{
int r = P1(); // Исключительная ситуация + выход из функции
Console.WriteLine("P2 done."); // Инструкция не сработает
return r; // Инструкция не сработает
}
static int P3()
{
int r = P2(); // Исключительная ситуация + выход из функции
Console.WriteLine("P3 done."); // Инструкция не сработает
return r; // Инструкция не сработает
}
static void Main(string[] args)
{
int r = P3(); // Исключительная ситуация + выход из программы
Console.WriteLine(r); // Инструкция не сработает
}
}
Обработка исключительной ситуации
class Program
{
static int P1()
{
int x = 7;
int y = 0;
int r = x / y; // Исключительная ситуация + выход из функции
Console.WriteLine("P1 done."); // Инструкция не сработает
return r; // Инструкция не сработает
}
static int P2()
{
int r = 0;
try
{
r = P1(); // Исключительная ситуация + переход на оператор catchбыла ли ошибка и если была, то какая
}
catch (Exception ex)
{
Console.WriteLine("Error."); // Обработка ИС
}
// ИС обработана нормальное выполнение
Console.WriteLine("P2 done.");
return r;
}
static int P3()
{
int r = P2();
Console.WriteLine("P3 done.");
return r;
}
static void Main(string[] args)
{
int r = P3();
Console.WriteLine(r);
}
}
Дополнительная литература
https://msdn.microsoft.com/ru-ru/library/ms173160.aspx http://professorweb.ru/my/csharp/charp_theory/level8/8_1.php http://mycsharp.ru/post/18/2013_06_10_obrabotka_isklyuchenij_v_si-sharp_operator_try-catch.html http://easyprog.ru/index.php?option=com_content&task=view&id=745&Itemid=54 http://habrahabr.ru/post/178805/