Boxing e Unboxing

Giorgio Borelli

Cos'è il boxing e unboxing del .NET frameworkIl Common Language Runtime (CLR) del .NET framework è in grado di eseguire applicazioni scritte in uno qualsiasi dei linguaggi supportati dalla piattaforma, quali C# o VB.NET, anche misti fra loro, questo è possibile grazie al Common Type System (CTS), ovvero l'insieme comune e condiviso dei tipi all'interno del framework.

In altre parole, ad esempio, il tipo int di C# ed integer di VB, durante l'esecuzione non sono altro che il tipo comune System.Int32 del framework.NET, tutto questo sempre ammesso che i linguaggi utilizzati soddisfino determinate specifiche (CLS - Common Language Specification) che li rendano compatibili con quelli comuni del framework.

Fatta questa premessa dovuta per avere un quadro più completo dell'argomento, diciamo che tra i tipi comuni del CLR, vi è un tipo generico da cui derivano tutti gli altri, il tipo System.Object, infatti si suole dire che nel .NET framework qualsiasi cosa è un'oggetto, sia questo un tipo intero, booleano o una classe stessa. La possibilità di avere un tipo generico che rappresenti qualsiasi dato all'interno del nostro programma ci consente di usarlo per potergli associare un qualsivoglia oggetto, sia esso un Tipo Valore o Tipo di Riferimento. Ad un primo impatto questo approccio potrebbe risultare molto comodo, uso solo tipi Object, e l'applicazione gira ugualmente, fregandomene della definizione dei tipi e della loro opportuna gestione.

Ma siamo certi che questo approccio sia corretto, purtroppo no, usare un tipo Object generico porta ad un decadimento delle prestazioni dell'applicazione, poichè avvengono le operazioni di Boxing e Unboxing per la conversione dà Tipi Valore a Tipi di Riferimento e viceversa, andiamo quindi a scoprirne di più su cosa avviene nelle operazioni di Boxing e Unboxing.

Se noi proviamo ad assegnare ad un tipo definito come Object un tipo intero, sebbene questa operazione sia perfettamente lecita (anche un'intero è un oggetto all'interno del framework.NET), andiamo in contro ad una operazione di gestione dei tipi detta di Boxing, ovvero una sorta di "cast", che converte il Tipo Valore (l'intero) in un Tipo di Riferimento (l'Object), nelle due righe di codice seguenti abbiamo un boxing dal Tipo Valore intero in ogeetto:

int num = 13;
Object o = (Object)num; //Boxing

Cosa accade al tipo durante l'operazione di Boxing? L'intero in questo caso, da Tipo Valore viene convertito in Tipo di Riferimento, con allocazione dallo stack nel managed heap e conseguente gestione in memoria attraverso la Garbage Collection.

L'operazione inversa, invece viene detta di Unboxing, cioè la conversione da un Tipo di Riferimento ad un Tipo Valore, le righe di codice seguenti mostrano un'operazione di unboxing da un tipo oggetto ad intero:

Object o = 13;
int num = (int)o; //Unboxing

Come vedete, dichiarare un tipo Object ed assegnargli un valore interò è un'operazione lecita, quando poi facciamo il cast da oggetto ad intero avviene l'Unboxing, in questa fase l'oggetto presente in memoria viene spostato dall'heap allo stack.

Fare Boxing ed Unboxing, sono operazioni costose, molto di più delle normali assegnazioni, durante il boxing il Tipo Valore deve essere convertito in un nuovo oggetto d'allocare nell'heap impegnango il processore; mentre con l'unboxing si ha l'operazione di spostamento inverso, ed entrambe comportano un cast  di tipo computazionalmente gravoso.

Nessuno vieta di trattare i tipi direttamente come oggetti generici, e ci sono circostanze in cui l'uso di un Object è giustificato, in generale però è meglio evitare le operazioni di Boxing ed Unboxing poichè comportano un decadimento generale delle prestazioni dell'applicazione.

Chiunque voglia aggiungere qualcosa in merito al Boxing ed Unboxing o porre una domanda può farlo tramite i commenti.

Categorie: .NET framework | C#

Tags: ,

Aggiungi Commento

biuquote
Loading