Condividi tramite


Boxing e unboxing (Guida per programmatori C#)

Aggiornamento: Luglio 2008

Il boxing è il processo di conversione di un tipo valore nel tipo object o in qualsiasi tipo di interfaccia implementato dal tipo valore. La conversione boxing di un tipo valore in CLR comporta il wrapping del valore in un System.Object e la sua archiviazione nell'heap gestito. L'unboxing consente invece di estrarre il tipo di valore dall'oggetto. Nell'esempio seguente viene eseguito il boxing della variabile integer i assegnandola all'oggetto o.

int i = 123;
object o = (object)i;  // boxing

È quindi possibile eseguire l'unboxing dell'oggetto o assegnandolo alla variabile integer i:

o = 123;
i = (int)o;  // unboxing

Prestazioni

Rispetto alle semplici assegnazioni, il boxing e l'unboxing sono processi onerosi dal punto di vista del calcolo. Il boxing di un tipo di valore comporta infatti l'allocazione e la costruzione di un nuovo oggetto. A un livello inferiore, anche il cast richiesto per l'unboxing è oneroso dal punto di vista del calcolo. Per ulteriori informazioni, vedere Prestazioni.

Boxing

Il boxing consente di archiviare tipi di valori nell'heap sottoposto a Garbage Collection. Il boxing è una conversione implicita di un tipo valore nel tipo object o in qualsiasi tipo di interfaccia implementato dal tipo valore. Il boxing di un tipo di valore prevede l'allocazione di un'istanza dell'oggetto nell'heap e quindi la copia del valore nel nuovo oggetto.

Si consideri la seguente dichiarazione di una variabile associata a un tipo che rappresenta un valore:

int i = 123;

L'istruzione seguente applica implicitamente l'operazione di boxing alla variabile i:

object o = i;  // Implicit boxing

Il risultato di questa istruzione è la creazione, sullo stack, di un riferimento all'oggetto o che fa riferimento a un valore di tipo int presente sull'heap. Questo valore è una copia di quello del tipo che rappresenta un valore assegnato alla variabile i. La differenza tra le due variabili i e o è illustrata nella seguente figura.

Conversione boxing

Grafica BoxingConversion

È inoltre possibile, anche se non indispensabile, eseguire il boxing in modo esplicito, come nell'esempio seguente:

int i = 123;
object o = (object)i;  // explicit boxing

Descrizione

In questo esempio la variabile integer i viene convertita in un oggetto o tramite boxing. Il valore archiviato nella variabile i viene quindi modificato da 123 a 456. Nell'esempio il tipo di valore originale e l'oggetto sottoposto a boxing utilizzano posizioni di memoria diverse, pertanto possono archiviare valori diversi.

Esempio

class TestBoxing
{
    static void Main()
    {
        int i = 123;
        object o = i;  // Implicit boxing

        i = 456;  // Change the contents of i

        System.Console.WriteLine("The value-type value = {0}", i);
        System.Console.WriteLine("The object-type value = {0}", o);
    }
}
/* Output:
    The value-type value = 456
    The object-type value = 123
*/

Nell'esempio riportato di seguito viene illustrato un caso di unboxing non valido, nonché l'eccezione InvalidCastException risultante. Se si utilizza try e catch, quando si verifica l'errore verrà visualizzato un messaggio di errore.

class TestUnboxing
{
    static void Main()
    {
        int i = 123;
        object o = i;  // implicit boxing

        try
        {
            int j = (short)o;  // attempt to unbox

            System.Console.WriteLine("Unboxing OK.");
        }
        catch (System.InvalidCastException e)
        {
            System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message);
        }
    }
}

Questo programma restituisce:

Specified cast is not valid. Error: Incorrect unboxing.

Se si modifica l'istruzione:

int j = (short) o;

in:

int j = (int) o;

la conversione verrà eseguita e si otterrà l'output

Unboxing OK.

Conversione unboxing

L'unboxing è una conversione esplicita dal tipo object a un tipo di valore o da un tipo di interfaccia a un tipo di valore che implementa tale interfaccia. Un'operazione di unboxing consiste di due passaggi successivi:

  • Controllo dell'istanza di oggetto per verificare che si tratti di un valore già sottoposto a boxing del tipo di valore dato.

  • Copia del valore dall'istanza alla variabile associata al tipo che rappresenta un valore.

Le istruzioni seguenti illustrano operazioni di boxing e unboxing:

int i = 123;      // a value type
object o = i;     // boxing
int j = (int)o;  // unboxing

La figura che segue illustra il risultato delle istruzioni precedenti.

Conversione unboxing

Rappresentazione grafica della conversione di UnBoxing

Per il corretto unboxing dei tipi di valore in fase di esecuzione, è necessario che l'elemento di cui eseguire l'unboxing faccia riferimento a un oggetto creato in precedenza tramite il boxing di un'istanza di tale tipo di valore. Se si tenta di eseguire l'unboxing di un valore null oppure di fare riferimento a un tipo di valore incompatibile, verrà generata un'eccezione InvalidCastException.

Specifiche del linguaggio C#

Per ulteriori informazioni, vedere le seguenti sezioni in Specifiche del linguaggio C#:

  • 4.3.1 Conversioni boxing

Sezioni correlate

Ulteriori informazioni:

Specifiche del linguaggio C#

Per ulteriori informazioni, vedere la seguente sezione inclusa in Specifiche del linguaggio C#:

  • 4.3 Boxing e unboxing

Vedere anche

Concetti

Guida per programmatori C#

Cronologia delle modifiche

Data

Cronologia

Motivo

Luglio 2008

Consolidati in questo argomento gli argomenti su conversione boxing e conversione unboxing, prima separati.

Correzione di errori nel contenuto.