- •13 Обработка исключительных ситуаций
- •13.1 Класс System.Exception
- •13.2 Основы обработки исключительных ситуаций
- •13.2.1 Применение пары ключевых слов try и catch
- •13.2.2 Простой пример обработки исключительной ситуации
- •13.2.3 Второй пример обработки исключительной ситуации
- •13.3 Последствия неперехвата исключений
- •13.4 Обработка исключительных ситуаций "изящный"
- •13.5 Применение нескольких операторов catch
- •13.6 Перехват всех исключений
- •13.7 Вложение блоков try
- •13.8 Генерирование исключений вручную
- •13.8.1 Повторное генерирование исключений
- •13.9 Использование блока finally
- •13.10 Подробное рассмотрение класса Exception
- •13.10.1 Наиболее часто используемые исключения
- •13.11 Получение производных классов исключений
- •13.12 Перехват исключений производных классов
- •13.13 Применение ключевых слов checked и unchecked
13.13 Применение ключевых слов checked и unchecked
В С# имеется специальное средство, связанное с генерированием исключений, возникающих при переполнении в арифметических вычислениях. Как вам должно быть уже известно, результаты некоторых видов арифметических вычислений могут превышать диапазон представления чисел для типа данных, используемого в вычислении. В этом случае происходит так называемое переполнение. Рассмотрим в качестве примера следующий фрагмент кода.
byte а, b, result;
а = 127; b = 127;
result = (byte)(а * b);
В этом коде произведение значений переменных а и b превышает диапазон представления чисел для типа byte. Следовательно, результат вычисления данного выражения приводит к переполнению для типа данных, сохраняемого в переменной result.
В С# допускается указывать, будет ли в коде сгенерировано исключение при переполнении, с помощью ключевых слов checked и unchecked. Так, если требуется указать, что выражение будет проверяться на переполнение, следует использовать ключевое слово checked, а если требуется проигнорировать переполнение ключевое слово unchecked. В последнем случае результат усекается, чтобы не выйти за пределы диапазона представления чисел для целевого типа выражения.
У ключевого слова checked имеются две общие формы. В одной форме проверяется конкретное выражение, и поэтому она называется операторной. А в другой форме проверяется блок операторов, и поэтому она называется блочной. Ниже приведены обе формы:
checked (выражение)
checked
{
// проверяемые операторы
}
где выражение обозначает проверяемое выражение. Если вычисление проверяемого выражения приводит к переполнению, то генерируется исключение OverflowException.
У ключевого слова unchecked также имеются две общие формы. В первой, операторной форме переполнение игнорируется при вычислении конкретного выражения. А во второй, блочной форме оно игнорируется при выполнении блока операторов:
unchecked (выражение)
unchecked
{
// операторы, для которых переполнение игнорируется
}
где выражение обозначает конкретное выражение, при вычислении которого переполнение игнорируется. Если же в непроверяемом выражении происходит переполнение, то результат его вычисления усекается.
Ниже приведен пример программы, в котором демонстрируется применение ключевых слов checked и unchecked.
Листинг 13.16
// Продемонстрировать применение ключевых слов checked и unchecked.
using System;
class CheckedDemo
{
static void Main()
{
byte a, b;
byte result;
a = 127;
b = 127;
try {
result = unchecked((byte)(a * b));
Console.WriteLine("Непроверенный на переполнение результат: " +
result);
result = checked((byte)(a * b)); // эта операция приводит к
// исключительной ситуации
Console.WriteLine("Проверенный на переполнение результат: " +
result); // не подлежит выполнению
}
catch (OverflowException exc)
{
Console.WriteLine(exc);
}
}
}
При выполнении этой программы получается следующий результат.
Непроверенный на переполнение результат: 1
System.OverflowException: Переполнение в результате
выполнения арифметической операции.
в CheckedDemo.Main() в <имя_файла>:строка 20
Как видите, результат вычисления непроверяемого выражения был усечен. А вычисление проверяемого выражения привело к исключительной ситуации.
В представленном выше примере программы было продемонстрировано применение ключевых слов checked и unchecked в одном выражении. А в следующем примере программы показывается, каким образом проверяется и не проверяется на переполнение целый блок операторов.
Листинг 13.17
// Продемонстрировать применение ключевых слов checked
// и unchecked в блоке операторов.
using System;
class CheckedBlocks
{
static void Main()
{
byte a, b;
byte result;
a = 127;
b = 127;
try
{
unchecked
{
a = 127;
b = 127;
result = unchecked((byte)(a * b));
Console.WriteLine("Непроверенный на переполнение результат: " +
result);
a = 125;
b = 5;
result = unchecked((byte)(a * b));
Console.WriteLine("Непроверенный на переполнение результат: " +
result);
}
checked
{
a = 2;
b = 7;
result = checked((byte)(a * b)); // правильно
Console.WriteLine("Проверенный на переполнение результат: " +
result);
a = 127;
b = 127;
result = checked((byte)(a * b)); // эта операция приводит к
// исключительной ситуации
Console.WriteLine("Проверенный на переполнение результат: " +
result); // не подлежит выполнению
}
}
catch (OverflowException exc)
{
Console.WriteLine(exc);
}
}
}
Результат выполнения этой программы приведен ниже.
Непроверенный на переполнение результат: 1
Непроверенный на переполнение результат: 113
Проверенный на переполнение результат: 14
System.OverflowException: Переполнение в результате
выполнения арифметической операции.
в CheckedDemo.Main() в <имя_файла>:строка 41
Как видите, результаты выполнения непроверяемого на переполнение блока операторов были усечены. Когда же в проверяемом блоке операторов произошло переполнение, то возникла исключительная ситуация.
Потребность в применении ключевого слова checked или unchecked может возникнуть, в частности, потому, что по умолчанию проверяемое или непроверяемое состояние переполнения определяется путем установки соответствующего параметра компилятора и настройки самой среды выполнения. Поэтому в некоторых программах состояние переполнения лучше проверять явным образом.
