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