Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Операторы checked
и unchecked
указывают контекст проверки переполнения для арифметических операций и преобразований целочисленного типа. Оператор по умолчанию unchecked
. Когда происходит арифметическое переполнение, контекст проверки переполнения определяет, что происходит. В проверяемом контексте выбрасывается 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
ключевые слова влияют на код.
Числовые типы и контекст проверки переполнения
Ключевые слова checked
и unchecked
в основном применяются к целочисленным типам, где существует адекватное поведение переполнения. Поведение обходного пути, в котором T.MaxValue + 1
становится T.MinValue
разумным в двух дополнительных значениях. Представленное значение неправильно, так как оно не может поместиться в хранилище для типа. Таким образом, биты представляют собой более низкие n-биты полного результата.
Для таких типов, как decimal
, float
double
и Half
которые представляют более сложное значение или дополнительное значение, оболочка не является разумной. Его нельзя использовать для вычисления больших или более точных результатов, поэтому unchecked
это не полезно.
float
, double
и Half
имеют разумные насыщенные значения для PositiveInfinity
и NegativeInfinity
, чтобы можно было обнаружить переполнение в контексте unchecked
. Таких ограничений для decimal
не существует, а насыщение на MaxValue
может привести к ошибкам или путанице. Операции, использующие decimal
, выбрасывают исключения как в контексте checked
, так и в unchecked
.
Операции, затронутые контекстом проверки переполнения
Контекст проверки переполнения влияет на следующие операции:
Следующие встроенные арифметические операторы: унарные ,
++
,--
и двоичные-
,+
,-
,*
операторы, когда операнды имеют целочисленный тип (то есть целочисленный числовой или символный тип) или тип перечисления.Явные числовые преобразования между целочисленными типами или от
float
double
до целочисленного типа.Примечание.
При преобразовании значения
decimal
в целочисленный тип и получения результата за пределами диапазона целевого типа, всегда выбрасывается OverflowException, независимо от контекста проверки переполнения.Начиная с C# 11, определяемые пользователем проверяемые операторы и преобразования. Дополнительные сведения см. в разделе Проверенные операторы, определяемые пользователем статьи Арифметические операторы.
Контекст проверки переполнения по умолчанию
Если контекст проверки переполнения не указан, значение параметра компилятора CheckForOverflowUnderflow определяет контекст по умолчанию для неконстантных выражений. По умолчанию значение этого параметра не задано, а целочисленные арифметические операции и преобразования выполняются в неконтролируемом контексте.
Константные выражения вычисляются по умолчанию в проверяемом контексте и переполнении вызывают ошибку во время компиляции. Вы можете явно указать непроверенный контекст для константного выражения с помощью оператора или выражения unchecked
.
Спецификация языка C#
Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:
- Операторы checked и unchecked
- Операторы checked и unchecked
- Определяемые пользователем операторы с проверкой и отменой проверки — C# 11