Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il boxing è il processo di conversione di un tipo valore nel tipo object
o in qualsiasi tipo di interfaccia implementato da questo tipo di valore. Quando il Common Language Runtime (CLR) effettua il boxing di un tipo valore, avvolge il valore all'interno di un'istanza System.Object e lo archivia nell'heap gestito. Unboxing estrae il tipo di valore dall'oggetto . Il boxing è implicito; l'unboxing è esplicito. Il concetto di boxing e unboxing alla base della visione unificata di C# del sistema di tipi, in cui un valore di qualsiasi tipo può essere trattato come oggetto.
Nell'esempio seguente, la variabile i
numero intero viene boxed e assegnata all'oggetto o
.
int i = 123;
// The following line boxes i.
object o = i;
L'oggetto o
può quindi essere estratto dalla scatola e assegnato alla variabile intera i
.
o = 123;
i = (int)o; // unboxing
Gli esempi seguenti illustrano come viene utilizzato il boxing in C#.
// String.Concat example.
// String.Concat has many versions. Rest the mouse pointer on
// Concat in the following statement to verify that the version
// that is used here takes three object arguments. Both 42 and
// true must be boxed.
Console.WriteLine(String.Concat("Answer", 42, true));
// List example.
// Create a list of objects to hold a heterogeneous collection
// of elements.
List<object> mixedList = new List<object>();
// Add a string element to the list.
mixedList.Add("First Group:");
// Add some integers to the list.
for (int j = 1; j < 5; j++)
{
// Rest the mouse pointer over j to verify that you are adding
// an int to a list of objects. Each element j is boxed when
// you add j to mixedList.
mixedList.Add(j);
}
// Add another string and more integers.
mixedList.Add("Second Group:");
for (int j = 5; j < 10; j++)
{
mixedList.Add(j);
}
// Display the elements in the list. Declare the loop variable by
// using var, so that the compiler assigns its type.
foreach (var item in mixedList)
{
// Rest the mouse pointer over item to verify that the elements
// of mixedList are objects.
Console.WriteLine(item);
}
// The following loop sums the squares of the first group of boxed
// integers in mixedList. The list elements are objects, and cannot
// be multiplied or added to the sum until they are unboxed. The
// unboxing must be done explicitly.
var sum = 0;
for (var j = 1; j < 5; j++)
{
// The following statement causes a compiler error: Operator
// '*' cannot be applied to operands of type 'object' and
// 'object'.
//sum += mixedList[j] * mixedList[j];
// After the list elements are unboxed, the computation does
// not cause a compiler error.
sum += (int)mixedList[j] * (int)mixedList[j];
}
// The sum displayed is 30, the sum of 1 + 4 + 9 + 16.
Console.WriteLine("Sum: " + sum);
// Output:
// Answer42True
// First Group:
// 1
// 2
// 3
// 4
// Second Group:
// 5
// 6
// 7
// 8
// 9
// Sum: 30
Prestazioni
In relazione alle semplici assegnazioni, il boxing e l'unboxing sono processi computazionali costosi. Quando un tipo di valore viene incapsulato, un nuovo oggetto deve essere allocato e costruito. In misura minore, anche il cast richiesto per unboxing è costoso dal punto di vista computazionale. Per altre informazioni, vedere Performance.
Boxe
Il boxing viene utilizzato per archiviare i tipi valore all'interno del sistema di Garbage Collection. Boxing è una conversione implicita di un tipo valore al tipo object
o a qualsiasi tipo di interfaccia implementato da questo tipo valore. L'incapsulamento di un tipo valore alloca un'istanza di oggetto nell'heap e copia il valore nel nuovo oggetto.
Si consideri la dichiarazione seguente di una variabile di tipo valore:
int i = 123;
L'istruzione seguente applica in modo implicito l'operazione boxing sulla variabile i
:
// Boxing copies the value of i into object o.
object o = i;
Il risultato di questa istruzione è la creazione di un riferimento o
all'oggetto , nello stack, che fa riferimento a un valore del tipo int
, nell'heap. Questo valore è una copia del valore di tipo valore assegnato alla variabile i
. La differenza tra le due variabili, i
e o
, è illustrata nell'immagine seguente della conversione boxing.
È anche possibile eseguire il boxing in modo esplicito come nell'esempio seguente, ma il boxing esplicito non è mai necessario:
int i = 123;
object o = (object)i; // explicit boxing
Esempio
In questo esempio viene convertita una variabile i
integer in un oggetto o
utilizzando il boxing. Il valore archiviato nella variabile i
viene quindi modificato da 123
a 456
. L'esempio mostra che il tipo di valore originale e l'oggetto boxed usano posizioni di memoria separate e pertanto possono archiviare valori diversi.
// Create an int variable
int i = 123;
// Box the value type into an object reference
object o = i; // boxing
// Display the initial values
Console.WriteLine($"Value of i: {i}");
Console.WriteLine($"Value of boxed object o: {o}");
// Modify the original value type
i = 456;
// Display the values after modification
Console.WriteLine("\nAfter changing i to 456:");
Console.WriteLine($"Value of i: {i}");
Console.WriteLine($"Value of boxed object o: {o}");
// Output:
// Value of i: 123
// Value of boxed object o: 123
// After changing i to 456:
// Value of i: 456
// Value of boxed object o: 123
Apertura della confezione
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 l'interfaccia. Un'operazione unboxing è costituita da:
Controllo dell'istanza dell'oggetto per verificare che sia un valore boxato del tipo di valore specificato.
Copia del valore dall'istanza nella variabile di tipo valore.
Le istruzioni seguenti illustrano le operazioni di boxing e di unboxing:
int i = 123; // a value type
object o = i; // boxing
int j = (int)o; // unboxing
La figura seguente illustra il risultato delle istruzioni precedenti:
Affinché l'unboxing dei tipi valore abbia esito positivo in fase di esecuzione, l'elemento sottoposto a unboxing deve essere un riferimento a un oggetto creato in precedenza eseguendo il boxing di un'istanza di tale tipo di valore. Provando a disimballare null
, provoca un NullReferenceException. Il tentativo di eseguire un unboxing su un riferimento a un tipo di valore incompatibile causa un'eccezione InvalidCastException.
Esempio
Nell'esempio seguente viene illustrato un caso di unboxing non valido e il risultato InvalidCastException
. Se si usa try
e catch
, viene visualizzato un messaggio di errore quando si verifica l'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($"{e.Message} Error: Incorrect unboxing.");
}
}
}
Questo programma restituisce:
Specified cast is not valid. Error: Incorrect unboxing.
Se si modifica l'istruzione :
int j = (short)o;
A:
int j = (int)o;
la conversione verrà eseguita e si otterrà l'output:
Unboxing OK.
Specifiche del linguaggio C#
Per ulteriori informazioni, consulta le Specifiche del linguaggio C# . La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.