Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Instrukcje checked i unchecked określają kontekst sprawdzania przepełnienia dla operacji arytmetycznych i konwersji typu całkowitego. Domyślna instrukcja to unchecked. Gdy występuje przepełnienie arytmetyczne liczb całkowitych, kontekst sprawdzania przepełnienia definiuje, co się dzieje. W zaznaczonym kontekście System.OverflowException jest zgłaszany element . Jeśli przepełnienie występuje w wyrażeniu stałym, wystąpi błąd czasu kompilacji. W niezaznaczonym kontekście wynik operacji jest obcinany przez odrzucenie wszystkich bitów o wysokiej kolejności, które nie mieszczą się w typie docelowym. Na przykład dodanie zawija się z maksymalnej wartości do wartości minimalnej. W poniższym przykładzie pokazano tę samą operację zarówno w kontekście zaznaczonym, jak i niezaznaczonej:
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 przepełnienia operatorów zdefiniowanych przez użytkownika i konwersji może różnić się od tego, który został opisany w poprzednim akapicie. W szczególności operatory sprawdzane 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 i Operatory sprawdzone zdefiniowane 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 mają wpływ 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 pierwsze wywołanie Multiply funkcji lokalnej pokazuje, że checked instrukcja nie ma wpływu na kontekst sprawdzania przepełnienia w Multiply ramach 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 kontekście sprawdzanym i powoduje wyjątek, ponieważ jest tekstowo wewnątrz bloku checked instrukcji .
Zachowanie i checkedunchecked zależy od typu i operacji. Nawet w przypadku liczb całkowitych operacje takie jak unchecked(x / 0) zawsze zgłaszane, ponieważ nie ma rozsądnego zachowania. Sprawdź zachowanie typu i operacji, aby zrozumieć, jak słowa checked kluczowe i unchecked wpływają na kod.
Typy liczbowe i kontekst sprawdzania przepełnienia
Słowa checked kluczowe i unchecked dotyczą głównie typów całkowitych, w których występuje rozsądne zachowanie przepełnienia. Zachowanie zawijania, w którym T.MaxValue + 1 staje się T.MinValue rozsądne w wartości uzupełniającej dwóch. Reprezentowana wartość nie jest poprawna , ponieważ nie może zmieścić się w magazynie dla typu. W związku z tym bity są reprezentatywne dla niższych n-bitów pełnego wyniku.
W przypadku typów, takich jak decimal, float, doublei Half reprezentujących bardziej złożoną wartość lub wartość uzupełniającą, zawijanie nie jest rozsądne. Nie można jej używać do obliczania większych lub bardziej dokładnych wyników, więc unchecked nie jest korzystne.
float, doublei Half mają rozsądne wartości saturujące dla PositiveInfinity i NegativeInfinity, dzięki czemu można wykryć przepełnienie w unchecked kontekście. W przypadku decimalprogramu nie istnieją takie limity, a saturacja w MaxValue programie może prowadzić do błędów lub nieporozumień. Operacje używające decimal rzutu zarówno w kontekście, jak i checkedunchecked .
Operacje, na które ma wpływ kontekst sprawdzania przepełnienia
Kontekst sprawdzania przepełnienia ma wpływ na następujące operacje:
Następujące wbudowane operatory arytmetyczne: jednoargumentowe ,
++--i binarne ,-+, i-operatory, gdy ich operandy są typu całkowitego (*lub/) lub typu wyliczenia.Jawne konwersje liczbowe między typami całkowitymi lub z
floatlubdoubledo typu całkowitego.Uwaga
Podczas konwertowania
decimalwartości na typ całkowity i wynik znajduje się poza zakresem typu docelowego, element jest zawsze zgłaszany, OverflowException niezależnie od kontekstu sprawdzania przepełnienia.Można użyć zdefiniowanych przez użytkownika operatorów i konwersji. 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ń niezdecydowanych. 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 zaznaczonym kontekście i przepełnienie powoduje 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 zaznaczone i niezaznaczone przez użytkownika