Операторы checked и unchecked
В С# предусмотрено специальное средство, которое связано с генерированием исключений, вызванных переполнением результата в арифметических вычислениях. Например, когда значение арифметического выражения выходит за пределы диапазона, определенного для типа данных выражения. Рассмотрим небольшой фрагмент программы:
static void Main()
{
byte x = 200; byte y = 200;
byte result = (byte) (x + y);
Console.WriteLine(result);
}
Здесь произведение значений а и b превышает диапазон представления значений типа byte. Следовательно, результат данного выражения не может быть записан в переменную result, тип которой byte.
Для управления подобными исключениями в С# используются операторы checked и unchecked. Чтобы указать, что некоторое выражение должно быть проконтролировано на предмет переполнения, используйте ключевое слово checked. А чтобы проигнорировать переполнение, используйте ключевое слово unchecked. В последнем случае результат будет усечен так, чтобы его тип соответствовал типу-результату выражения.
Замечание. По умолчанию проверка переполнения отключена (галочка не стоит). В результате код выполняется быстро, но тогда программист должен быть уверен, что переполнения не случится или предусмотреть его возникновение. Как мы уже упоминали, можно включить проверку переполнения для всего проекта, однако она не всегда нужна. С помощью использования операторов checked и unchecked в С# реализуется механизм гибкого управления проверкой
Можно задать (или отключить) проверку переполнения сразу для всего проекта. Для этого необходимо выполнить следующие действия
- Щелкнуть правой кнопкой мыши на имени проекта
- В выпадающем меню выбрать Properties
- В появившемся окне (см. рис.) выбрать слева страницу Build
- Щелкнуть на кнопке Advanced
- В появившемся окошке поставить или убрать галочку напротив Check for arithmetic overflow/underflow property.
Оператор checked имеет две формы:
1) проверяет конкретное выражение и называется операторной checked-формой
checked ((тип-выражения) expr)
где expr — выражение, значение которого необходимо контролировать. Если значение контролируемого выражения переполнилось, генерируется исключение типа OverflowException.
2) проверяет блок инструкций
checked
{
// Инструкции, подлежащие проверке.
}
Оператор unchecked также имеет две формы:
5) операторная форма, которая позволяет игнорировать переполнение для заданного выражения
unchecked ((тип-выражения) expr)
где ехрr — выражение, которое не проверяется на предмет переполнения. В случае переполнения это выражение усекается.
6) игнорирует переполнение, которое возможно в блоке инструкций
unchecked
{
// Инструкции, для которых переполнение игнорируется.
}
Рассмотрим пример программы, которая демонстрирует использование checked и unchecked.
static void Main()
{
byte x = 200; byte y = 200;
try
{
byte result = unchecked((byte)(x + y));
Console.WriteLine("1: {0}", result);
result = checked((byte)(x + y));
Console.WriteLine("2: ", result);
}
catch (OverflowException)
{
Console.WriteLine("возникло переполнение");
}
}
Результат выполнения программы:
1: 144
возникло переполнение
Задание. Уберите блок uncheсked. Посмотрите, что изменится в выполнении программы и дайте этому объяснение
В данном примере мы посмотрели, как использовать checked и uncheсked для проверки выражения. А теперь посмотрим, как использовать их для контроля за блоком инструкций.
static void Main()
{
byte n = 1; byte i;
try
{
unchecked //блок без проверки
{
for (i = 1; i < 10; i++) n *= i;
Console.WriteLine("1: {0}", n);
}
checked //блок с проверкой
{
n=1;
for (i = 1; i < 10; i++) n *= i;
Console.WriteLine("2: ", n);
}
}
catch (OverflowException)
{
Console.WriteLine("возникло переполнение");
}
}
Результат выполнения программы:
1: 128
возникло переполнение
Задание. Поменяйте местами блоки unchecked и checked. Посмотрите, что изменится в выполнении программы и дайте этому объяснение