Шаг 227.
Язык программирования C#. Начала.
Обработка исключений. Инструкции checked и unchecked

    На этом шаге мы рассмотрим назначение и пример использования этих инструкций.

    В некоторых случаях удобно использовать инструкции checked и unchecked. С помощью инструкции checked можно выделить блок или выражение, которые в таком случае контролируются на предмет переполнения (выхода значения за допустимые границы). Если происходит переполнение, то генерируется исключение класса OverflowException. Шаблон использования инструкции checked для выделения блока команд такой:

checked {
  // Команды
}
Если мы хотим контролировать отдельное выражение, то шаблон использования инструкции checked будет следующим:
  checked(выражение)

    Напротив, инструкция unchecked используется, если мы не хотим, чтобы при переполнении генерировалось исключение класса OverflowException. Шаблоны использования инструкции unchecked такие же, как и для инструкции checked. Если с помощью инструкции unchecked контролируем блок кода, то используем такой шаблон:

unchecked {
  // Команды
}

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

  unchecked(выражение)

    Стоит сразу заметить, что по умолчанию используется режим, при котором исключения в случае переполнения не генерируется. С другой стороны, использование инструкций checked и unchecked оправдывается тем, что в общем случае могут быть задействованы разные глобальные настройки среды выполнения и применение инструкций позволит в явном виде идентифицировать способ реагирования на возникновение переполнения.

    Программа, в которой есть пример использования инструкций checked и unchecked, представлена ниже.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace pr227_1
{
    // Класс с главным методом: 
    class Program
    {
        // Главный метод: 
        static void Main()
        {
            // Переменные: 
            byte a = 100, b = 200, c;
            // Контролируемый код: 
            try {
                // Проверка на предмет переполнения: 
                c = checked((byte)(a + b));
            }
            // Обработка исключения: 
            catch(OverflowException) {
                Console.WriteLine("Есть ошибка: " + (a + b));
            }
            // Нет проверки на предмет переполнения: 
            c = unchecked((byte)(a + b));
            Console.WriteLine("Heт ошибки: " + c);
            // Задержка:
            Console.ReadLine();
        }
    }
}
Архив проекта можно взять здесь.

    Результат выполнения программы будет следующим:


Рис.1. Результат выполнения программы

    Программа очень простая. В главном методе объявляются три переменные типа byte: переменная a со значением 100, переменная b со значением 200 и переменная c, значение которой при объявлении не присваивается.

    Значение переменной c сначала присваивается командой

  c = checked((byte)(a + b));
внутри try-блока. Сумма значений переменных a и b равна 300, и это число выходит за верхнюю допустимую границу 255. Поскольку соответствующее выражение помечено инструкцией checked, то генерируется исключение класса OverflowException. Оно перехватывается и обрабатывается в catch-блоке. Там выполняется команда
  Console.WriteLine("Есть ошибка: " + (a + b));              , 
и реальная сумма значений переменных a и b появляется в диалоговом окне.

    Еще раз значение переменной c присваивается командой

  c = unchecked((byte)(a + b));            . 
Но теперь мы использовали инструкцию unchecked. Поэтому исключение, связанное с выходом за верхнюю границу значения, присваиваемого переменной c, не генерируется.


Если бы мы не использовали инструкцию unchecked, то исключение тоже не генерировалось бы. Напомним, этот режим используется по умолчанию.

    Фактическое значение переменной c проверяем с помощью команды

  Console.WriteLine("Heт ошибки: " + c);     .


Присваиваемое переменной c значение 300 можно представить в виде
  300 = 256 + 44 = 256 + 32 + 8 + 4 = 28 + 25 + 23 + 22. 
Но для записи значений типа byte отводится всего 8 битов. В присваиваемом значении старшие биты отбрасываются (то есть пропадает слагаемое 28). Переменная c получает значение
  25 + 23 + 22 = 32 + 8 + 4 = 44.

    На следующем шаге мы рассмотрим примеры использования исключений.




Предыдущий шаг Содержание Следующий шаг