Проверенные и снятые операторы (справочник по C#)

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

uint a = uint.MaxValue;

unchecked
{
    Console.WriteLine(a + 3);  // output: 2
}

try
{
    checked
    {
        Console.WriteLine(a + 3);
    }
}
catch (OverflowException e)
{
    Console.WriteLine(e.Message);  // output: Arithmetic operation resulted in an overflow.
}

Примечание.

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

Дополнительные сведения см. в разделах арифметических переполнений и деления по нулю и определяемым пользователем операторам статьи арифметических операторов.

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

double a = double.MaxValue;

int b = unchecked((int)a);
Console.WriteLine(b);  // output: -2147483648

try
{
    b = checked((int)a);
}
catch (OverflowException e)
{
    Console.WriteLine(e.Message);  // output: Arithmetic operation resulted in an overflow.
}

Операторы checked и unchecked операторы влияют только на контекст проверки переполнения для этих операций, которые текстуально находятся внутри блока инструкций или круглых скобок оператора, как показано в следующем примере:

int Multiply(int a, int b) => a * b;

int factor = 2;

try
{
    checked
    {
        Console.WriteLine(Multiply(factor, int.MaxValue));  // output: -2
    }
}
catch (OverflowException e)
{
    Console.WriteLine(e.Message);
}

try
{
    checked
    {
        Console.WriteLine(Multiply(factor, factor * int.MaxValue));
    }
}
catch (OverflowException e)
{
    Console.WriteLine(e.Message);  // output: Arithmetic operation resulted in an overflow.
}

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

Поведение checked и unchecked зависит от типа и операции. Даже для целых чисел операции, как unchecked(x / 0) всегда, бросают, потому что нет разумного поведения. Проверьте поведение типа и операции, чтобы понять, как checked unchecked ключевые слова влияют на код.

Числовые типы и контекст проверки переполнения

unchecked Ключевые checked слова в основном применяются к целочисленным типам, где есть разумное поведение переполнения. Поведение обходного пути, в котором T.MaxValue + 1 становится T.MinValue разумным в двух дополнительных значениях. Представленное значение неправильно, так как оно не может поместиться в хранилище для типа. Таким образом, биты представляют собой более низкие n-биты полного результата.

Для таких типов, как decimal, floatdoubleи Half которые представляют более сложное значение или дополнительное значение, оболочка не является разумной. Его нельзя использовать для вычисления больших или более точных результатов, поэтому unchecked это не полезно.

float, doubleи Half имеют разумные насыщенные значения для PositiveInfinity и NegativeInfinity, чтобы можно было обнаружить переполнение в контексте unchecked . Для decimalэтого не существует таких ограничений, а насыщенность MaxValue может привести к ошибкам или путанице. Операции, использующие decimal вызов как в контексте checked , так и unchecked в контексте.

Операции, затронутые контекстом проверки переполнения

Контекст проверки переполнения влияет на следующие операции:

Контекст проверки переполнения по умолчанию

Если контекст проверки переполнения не указан, значение параметра компилятора CheckForOverflowUnderflow определяет контекст по умолчанию для неконстантных выражений. По умолчанию значение этого параметра не задано, а арифметические операции целочисленного типа и преобразования выполняются в неконтролируемом контексте.

Константные выражения вычисляются по умолчанию в проверяемом контексте и переполнении вызывают ошибку во время компиляции. Вы можете явно указать без флажок контекст для константного выражения с оператором или оператором unchecked .

Спецификация языка C#

Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:

См. также