checked und unchecked Anweisungen (C#-Referenz)
Mit den Anweisungen checked
und unchecked
wird der Überlaufprüfungskontext für arithmetische Operationen und Konvertierungen vom integralen Typ gesteuert. Wenn ein arithmetischer Integerüberlauf auftritt, definiert der Überlaufprüfungskontext wie folgt, was geschieht. In einem checked-Kontext wird eine System.OverflowException ausgelöst, wenn bei einem Überlauf in einem konstanten Ausdruck ein Kompilierzeitfehler auftritt. In einem unchecked-Kontext wird das Ergebnis der Operation gekürzt, indem alle höherwertigen Bits verworfen werden, die nicht in den Zieltyp passen. Im Falle einer Addition wird z. B. alles vom Höchstwert bis zum Mindestwert umschlossen. Das folgende Beispiel zeigt denselben Vorgang in einem checked- und in einem unchecked-Kontext:
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.
}
Hinweis
Das Verhalten von benutzerdefinierten Operatoren und Konvertierungen im Fall des Überlaufs kann von dem im vorherigen Absatz beschriebenen Verhalten abweichen. Insbesondere lösen benutzerdefinierte checked-Operatoren möglicherweise keine Ausnahme in einem checked-Kontext aus.
Weitere Informationen finden Sie im Artikel Arithmetische Operatoren in den Abschnitten Arithmetischer Überlauf und Division durch Null und Benutzerdefinierte checked-Operatoren.
Um den Kontext der Überlaufüberprüfung für einen Ausdruck anzugeben, können Sie auch die Operatoren checked
und unchecked
verwenden, wie im folgenden Beispiel gezeigt:
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.
}
Die checked
- und unchecked
-Anweisungen und -Operatoren wirken sich nur für Operationen, die sich textlich innerhalb des Anweisungsblocks oder der Klammern des Operators befinden, auf den Kontext der Überlaufüberprüfung für Operationen aus, wie im folgenden Beispiel gezeigt:
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.
}
Im vorherigen Beispiel zeigt der erste Aufruf der lokalen Multiply
-Funktion, dass sich die checked
-Anweisung nicht auf den Kontext der Überlaufüberprüfung innerhalb der Multiply
-Funktion auswirkt, da keine Ausnahme ausgelöst wird. Beim zweiten Aufruf der Multiply
-Funktion wird der Ausdruck, der das zweite Argument der Funktion berechnet, in einem checked-Kontext ausgewertet und führt zu einer Ausnahme, da er sich textlich innerhalb des Blocks der checked
-Anweisung befindet.
Vom Kontext der Überlaufüberprüfung betroffene Operationen
Der Kontext der Überlaufüberprüfung wirkt sich auf die folgenden Operationen aus:
Die folgenden integrierten arithmetischen Operatoren: unäre
++
-,--
-,-
- und binäre+
-,-
-,*
- und/
-Operatoren, wenn ihre Operanden vom integralen Typ sind (d. h. entweder integraler numerischer Typ oder char-Typ ) oder enum-Typ.Explizite numerische Konvertierungen zwischen ganzzahligen Typen oder von
float
oderdouble
in einen integralen Typ.Hinweis
Wenn Sie einen
decimal
-Wert in einen integralen Typ konvertieren und das Ergebnis außerhalb des Bereichs des Zieltyps liegt, wird unabhängig vom Kontext der Überlaufüberprüfung immer eine OverflowException ausgelöst.Ab C# 11 werden benutzerdefinierte checked-Operatoren und -Konvertierungen durchgeführt. Weitere Informationen finden Sie im Abschnitt Benutzerdefinierte checked-Operatoren des Artikels Arithmetische Operatoren.
Standardmäßiger Kontext der Überlaufüberprüfung
Wenn Sie den Kontext der Überlaufüberprüfung nicht angeben, definiert der Wert der CheckForOverflowUnderflow-Compileroption den Standardkontext für nicht konstante Ausdrücke. Standardmäßig ist der Wert dieser Option nicht festgelegt, und arithmetische Operationen des Integraltyps werden in einem unchecked-Kontext ausgeführt.
Konstante Ausdrücke werden standardmäßig in einem checked-Kontext ausgewertet, und bei einem Überlauf tritt ein Kompilierzeitfehler auf. Sie können einen unchecked-Kontext für einen konstanten Ausdruck explizit mit unchecked
-Anweisung oder -Operator angeben.
C#-Sprachspezifikation
Weitere Informationen finden Sie in den folgenden Abschnitten der C#-Sprachspezifikation:
- The checked and unchecked statements (Geprüfte und nicht geprüfte Anweisungen)
- The checked and unchecked operators (Checked- und Unchecked-Operatoren)
- Benutzerdefinierte checked- und unchecked-Operatoren – C# 11