Condividi tramite


Istruzioni checked e unchecked (Riferimenti per C#)

Le istruzioni checked e unchecked vengono usate per verificare il contesto di controllo dell'overflow per le conversioni e le operazioni aritmetiche di tipo integrale. Quando si verifica l'overflow aritmetico di numeri interi, il contesto di controllo dell'overflow definisce cosa accade. In un contesto controllato viene generata una System.OverflowException; se l'overflow si verifica in un'espressione costante, si verifica un errore in fase di compilazione. In un contesto non verificato, il risultato dell'operazione viene troncato rimuovendo tutti i bit di ordine elevato che non rientrano nel tipo di destinazione. Ad esempio, l'addizione esegue il wrapping dal valore massimo al valore minimo. L'esempio seguente mostra la stessa operazione in un contesto verificato e non verificato:

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.
}

Nota

Il comportamento di overflow degli operatori e delle conversioni definiti dall'utente può essere diverso da quello descritto nel paragrafo precedente. In particolare, gli operatori verificati definiti dall'utente potrebbero non generare un'eccezione in un contesto controllato.

Per altre informazioni, vedere le sezioni Overflow aritmetico e divisione per zero e Operatori verificati definiti dall'utente dell'articolo Operatori aritmetici.

Per specificare il contesto di controllo dell'overflow per un'espressione, è anche possibile usare gli operatori checked e unchecked, come illustrato nell'esempio seguente:

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.
}

Le istruzioni e gli operatori checked e unchecked influiscono solo sul contesto di controllo dell'overflow per le operazioni che sono testualmente all'interno delle parentesi del blocco di istruzioni o dell'operatore, come illustrato nell'esempio seguente:

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.
}

Nell'esempio precedente, la prima chiamata della funzione locale Multiply mostra che l'istruzione checked non influisce sul contesto di controllo dell'overflow all'interno della funzione Multiply perché non viene generata alcuna eccezione. Alla seconda chiamata della funzione Multiply, l'espressione che calcola il secondo argomento della funzione viene valutata in un contesto controllato e restituisce un'eccezione mentre è testualmente all'interno del blocco dell'istruzione checked.

Il comportamento di checked e unchecked dipende dal tipo e dall'operazione. Anche per i numeri interi, le operazioni come unchecked(x / 0) sempre generano perché non esiste alcun comportamento sensato. Controllare il comportamento per il tipo e l'operazione per comprendere in che modo le checked parole chiave e unchecked influiscono sul codice.

Tipi numerici e contesto di controllo dell'overflow

Le checked parole chiave e unchecked si applicano principalmente ai tipi integrali in cui è presente un comportamento di overflow sensibile. Il comportamento wraparound in cui T.MaxValue + 1 diventa T.MinValue sensibile nel valore di complemento di due. Il valore rappresentato non è corretto perché non può rientrare nello spazio di archiviazione per il tipo. Di conseguenza, i bit sono rappresentativi dei n bit inferiori del risultato completo.

Per i tipi come decimal, doublefloat, e Half che rappresentano un valore più complesso o un valore di complemento, wraparound non è ragionevole. Non può essere usato per calcolare risultati più grandi o più accurati, quindi unchecked non è utile.

float, doublee Half hanno valori di saturazione sensibili per PositiveInfinity e NegativeInfinity, in modo da poter rilevare l'overflow in un unchecked contesto. Per decimal, non esistono limiti di questo tipo e la saturazione in MaxValue può causare errori o confusione. Operazioni che usano decimal generano un'eccezione sia in un contesto che in un checked unchecked contesto.

Operazioni interessate dal contesto di controllo dell'overflow

Il contesto di controllo dell'overflow influisce sulle operazioni seguenti:

Contesto di controllo overflow predefinito

Se non si specifica il contesto di controllo dell'overflow, il valore dell'opzione del compilatore CheckForOverflowUnderflow definisce il contesto predefinito per le espressioni non costanti. Per impostazione predefinita, il valore di tale opzione è unset e le operazioni aritmetiche di tipo integrale e le conversioni vengono eseguite in un contesto non verificato.

Le espressioni costanti vengono valutate per impostazione predefinita in un contesto controllato e l'overflow causa un errore in fase di compilazione. È possibile specificare in modo esplicito un contesto non verificato per un'espressione costante con l'istruzione o l'operatore unchecked.

Specifiche del linguaggio C#

Per altre informazioni, vedere le sezioni seguenti delle specifiche del linguaggio C#:

Vedi anche