zaznaczone i niezaznaczone instrukcje (odwołanie w C#)
Instrukcje checked
i unchecked
określają kontekst sprawdzania przepełnienia dla operacji arytmetycznych i konwersji typu całkowitego. Gdy wystąpi przepełnienie arytmetyczne liczb całkowitych, kontekst sprawdzania przepełnienia definiuje, co się dzieje. W zaznaczonym kontekście System.OverflowException jest zgłaszany błąd. Jeśli przepełnienie występuje w wyrażeniu stałym, wystąpi błąd czasu kompilacji. W nieznakowanym kontekście wynik operacji jest obcięty przez odrzucenie wszystkich bitów o wysokiej kolejności, które nie mieszczą się w typie docelowym. Na przykład w przypadku dodania opakowuje wartość maksymalną do wartości minimalnej. W poniższym przykładzie pokazano tę samą operację zarówno w zaznaczonym, jak i niezaznakowanym kontekście:
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.
}
Uwaga
Zachowanie operatorów zdefiniowanych przez użytkownika i konwersji w przypadku przepełnienia może się różnić od tego, który został opisany w poprzednim akapicie. W szczególności operatory zaznaczone przez użytkownika mogą nie zgłaszać wyjątku w zaznaczonym kontekście.
Aby uzyskać więcej informacji, zobacz sekcje Przepełnienie arytmetyczne i dzielenie według zera oraz Operatory zaznaczone przez użytkownika w artykule Operatory arytmetyczne .
Aby określić kontekst sprawdzania przepełnienia dla wyrażenia, można również użyć checked
operatorów i unchecked
, jak pokazano w poniższym przykładzie:
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.
}
Instrukcje checked
i unchecked
i operatory wpływają tylko na kontekst sprawdzania przepełnienia dla tych operacji, które są tekstowo wewnątrz bloku instrukcji lub nawiasów operatora, jak pokazano w poniższym przykładzie:
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.
}
W poprzednim przykładzie pierwsza wywołanie Multiply
funkcji lokalnej pokazuje, że checked
instrukcja nie wpływa na kontekst sprawdzania przepełnienia w Multiply
funkcji, ponieważ nie jest zgłaszany żaden wyjątek. Podczas drugiego Multiply
wywołania funkcji wyrażenie, które oblicza drugi argument funkcji, jest obliczane w zaznaczonym kontekście i powoduje wyjątek, ponieważ jest tekstowo wewnątrz bloku checked
instrukcji .
Operacje, których dotyczy kontekst sprawdzania przepełnienia
Kontekst sprawdzania przepełnienia wpływa na następujące operacje:
Następujące wbudowane operatory arytmetyczne: jednoargumentowe
++
,--
-
i binarne+
,-
,*
i/
operatory, gdy ich operandy mają typ całkowity (czyli całkowity typ liczbowy lub char) lub typ wyliczenia.Jawne konwersje liczbowe między typami całkowitymi lub z
float
lubdouble
do typu całkowitego.Uwaga
Podczas konwertowania
decimal
wartości na typ całkowity i wynik znajduje się poza zakresem typu docelowego, jest zawsze zgłaszany, OverflowException niezależnie od kontekstu sprawdzania przepełnienia.Począwszy od języka C# 11, zdefiniowane przez użytkownika operatory i konwersje. Aby uzyskać więcej informacji, zobacz sekcję Operatory zaznaczone przez użytkownika w artykule Operatory arytmetyczne .
Domyślny kontekst sprawdzania przepełnienia
Jeśli nie określisz kontekstu sprawdzania przepełnienia, wartość opcji kompilatora CheckForOverflowUnderflow definiuje domyślny kontekst dla wyrażeń niestałych. Domyślnie wartość tej opcji jest niezwiązana, a operacje arytmetyczne i konwersje typu całkowitego są wykonywane w nieznakowanym kontekście.
Wyrażenia stałe są domyślnie oceniane w kontekście zaznaczonym, a w przypadku przepełnienia występuje błąd czasu kompilacji. Można jawnie określić nieznakowany kontekst dla wyrażenia stałego za pomocą instrukcji unchecked
lub operatora.
specyfikacja języka C#
Aby uzyskać więcej informacji, zobacz następujące sekcje specyfikacji języka C#:
- Zaznaczone i niezaznaczone instrukcje
- Zaznaczone i niezaznaczone operatory
- Operatory zdefiniowane przez użytkownika i niezaznaczone — C# 11