Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Mit den Anweisungen checked
und unchecked
wird der Überlaufprüfungskontext für arithmetische Operationen und Konvertierungen vom integralen Typ gesteuert. Die Standard-Anweisung lautet unchecked
. Wenn ein arithmetischer Integerüberlauf auftritt, definiert der Überlaufprüfungskontext wie folgt, was geschieht. In einem überprüften Kontext wird eine System.OverflowException ausgelöst; tritt ein Überlauf in einem konstanten Ausdruck auf, so führt dies zu einem Kompilierzeitfehler. In einem nicht überprüften Kontext wird das Ergebnis der Operation gekürzt, indem alle höherwertigen Bits verworfen werden, die nicht in den Zieltyp passen. Zum Beispiel geht die Addition vom Maximalwert zum Minimalwert über. Das folgende Beispiel zeigt denselben Vorgang sowohl in einem "checked"- als auch 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 Überlaufverhalten von benutzerdefinierten Operatoren und Konvertierungen kann sich von der im vorherigen Absatz beschriebenen unterscheiden. 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 geprüfte 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 beeinflussen nur den Kontext der Überlaufüberprüfung für jene Operationen, die sich inhaltlich innerhalb des Anweisungsblocks oder der Klammern des Operators befinden, wie im folgenden Beispiel gezeigt wird.
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.
Das Verhalten von checked
und unchecked
hängt vom Typ und vom Vorgang ab. Selbst bei ganzen Zahlen führen Operationen wie unchecked(x / 0)
immer zum Überlauf, weil es kein vernünftiges Verhalten gibt. Überprüfen Sie das Verhalten für den Typ und den Vorgang, um zu verstehen, wie sich die checked
Und unchecked
Schlüsselwörter auf Ihren Code auswirken.
Numerische Typen und Überlaufprüfungskontext
Die Schlüsselwörter checked
und unchecked
gelten in erster Linie für integrale Datentypen, wo ein sinnvolles Überlaufverhalten vorhanden ist. Das Wraparound-Verhalten, bei dem T.MaxValue + 1
zu T.MinValue
wird, ist bei einem Zweierkomplement-Wert sinnvoll. Der dargestellte Wert ist nicht korrekt , da er nicht in den Speicher für den Typ passt. Daher sind die Bits repräsentativ für die unteren n-Bits des vollständigen Ergebnisses.
Bei Typen wie decimal
, float
, double
und Half
, die einen komplexeren Wert oder einen Einerkomplementwert darstellen, ist Wraparound nicht sinnvoll. Es kann nicht verwendet werden, um größere oder genauere Ergebnisse zu berechnen, daher unchecked
ist es nicht vorteilhaft.
float
, double
und Half
verfügen über vernünftige Sättigungswerte für PositiveInfinity
und NegativeInfinity
, damit Sie Überlauf in einem unchecked
Kontext erkennen können. Für decimal
gibt es keine solchen Grenzen, und die Sättigung bei MaxValue
kann zu Fehlern oder Verwirrung führen. Operationen, die decimal
verwenden, werfen sowohl in einem checked
- als auch in einem unchecked
-Kontext.
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 Überprüfte Operatoren des Artikels Arithmetische Operatoren.
Standardmäßiger Kontext der Überlaufüberprüfung
Wenn Sie den Überlaufüberprüfungskontext nicht angeben, definiert der Wert der CheckForOverflowUnderflow-Compileroption den Standardkontext für nicht zusammenhängende Ausdrücke. Standardmäßig ist der Wert dieser Option nicht festgelegt, und arithmetische Operationen des Integraltyps werden in einem unchecked-Kontext ausgeführt.
Konstantenausdrücke werden standardmäßig in einem überprüften Kontext ausgewertet, und Überlauf verursacht einen Kompilierzeitfehler. 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:
- Die geprüften und ungeprüften Anweisungen
- Die geprüften und ungeprüften Operatoren
- Benutzerdefinierte geprüfte und nicht geprüfte Operatoren – C# 11