Freigeben über


Die aktivierten und deaktivierten 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. Das Hinzufügen wird beispielsweise von dem Maximalwert bis zum Minimalwert umbrochen. 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 Ü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 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.

Das Verhalten und checked unchecked hängt vom Typ und vom Vorgang ab. Auch für ganze Zahlen werden Vorgänge wie unchecked(x / 0) immer ausgelöst, da kein vernünftiges Verhalten vorhanden ist. Ü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 Überlaufüberprüfungskontext

Die checked Schlüsselwörter unchecked gelten in erster Linie für integrale Typen, bei denen ein vernünftiges Überlaufverhalten vorhanden ist. Das Wraparound-Verhalten, bei dem T.MaxValue + 1 in einem Zwei-Ergänzungswert sinnvoll wird T.MinValue . 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.

Für Typen wie decimal, float, doubleund Half die einen komplexeren Wert oder den Ergänzungswert eines betreffenden Darstellens 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, doubleund 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 , gibt decimales keine solchen Grenzen, und die Sättigung an MaxValue kann zu Fehlern oder Verwirrung führen. Vorgänge, die decimal ausgelöst werden, sowohl in einem als unchecked auch in einem checked Kontext.

Vom Kontext der Überlaufüberprüfung betroffene Operationen

Der Kontext der Überlaufüberprüfung wirkt sich auf die folgenden Operationen aus:

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 in einem überprüften Kontext standardmäßig ausgewertet, und überlauf verursacht einen Kompilierungszeitfehler. 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:

Weitere Informationen