Ответ 1
У Эрика Липперта есть запись в блоге из двух частей: "Для чего нужно ключевое слово без контроля?": Часть 1 - Часть 2
"Проверено" - это ключевое слово блока, которое включает проверку арифметического переполнения. Обычно, если целочисленная операция превышает максимальное или минимальное значение, которое может обрабатывать тип, операция все равно продолжается, и результат просто повторяется, как одометр. Так, например:
byte b = byte.MaxValue;
Console.WriteLine(b); // 255 (11111111)
Console.WriteLine(++b); // 0 (00000000)
Помещение этого фрагмента в checked
блок предотвращает переполнение, и вместо этого среда выполнения генерирует OverflowException
:
checked
{
byte b = byte.MaxValue;
Console.WriteLine(b); // b=255
try
{
Console.WriteLine(++b);
}
catch (OverflowException e)
{
Console.WriteLine(e.Message); // "Arithmetic operation resulted in an overflow."
// b = 255
}
}
А так как есть опция компилятора /checked
, которая включает проверку компилятора по умолчанию, есть также ключевое слово unchecked
которое предотвращает проверку переполнения.
Что касается использования, проверка переполнения должна использоваться экономно, как и в случае обработки исключений в целом. Чтобы проверить переполнение во время выполнения, он значительно быстрее (например, на порядок) выполняет простую проверку, а не включает проверку переполнения:
int multiply(int i, int j)
{
if ((long)i * (long)j > int.MaxValue)
throw new InvalidOperationException("overflow");
return i*j;
}
Вы можете сделать это даже для Int64/long, используя BigInteger
(это может быть как минимум на порядок быстрее, чем при использовании checked
):
long multiply(long i, long j)
{
if (new System.Numerics.BigInteger(i) + j > long.MaxValue)
throw new InvalidOperationException("overflow");
return i*j;
}
Там также есть хорошая статья о проекте кода, которая объясняет некоторые предостережения (например, проверка переполнения применяется только к непосредственному блоку кода, а не к каким-либо вызовам функций внутри блока).