Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Boxing est le processus de conversion d’un type valeur en type object
ou en n’importe quel type d’interface implémenté par ce type valeur. Lorsque le Common Language Runtime (CLR) boxe un type de valeur, il encapsule la valeur à l’intérieur d’une System.Object instance et le stocke sur le tas managé. L'unboxing extrait le type valeur de l'objet. La conversion boxing est implicite ; la conversion unboxing est explicite. Le concept de boxe et de déboxing sous-tend l’affichage unifié C# du système de type dans lequel une valeur de n’importe quel type peut être traitée comme un objet.
Dans l’exemple suivant, la variable i
entière est boxée et affectée à l’objet o
.
int i = 123;
// The following line boxes i.
object o = i;
L’objet o
peut ensuite être unboxed et affecté à la variable i
entière :
o = 123;
i = (int)o; // unboxing
Les exemples suivants illustrent l’utilisation de boxe en 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
Performances
En ce qui concerne les affectations simples, la boxe et le déboxing sont des processus coûteux en termes de calcul. Lorsqu’un type valeur est boxé, un nouvel objet doit être alloué et construit. Dans une moindre mesure, la conversion requise pour unboxing est également coûteuse en calcul. Pour plus d’informations, consultez Performance.
Boxe
La boxe est utilisée pour stocker les types de valeurs dans le tas collecté par le garbage. Boxing est une conversion implicite d’un type valeur en type object
ou en n’importe quel type d’interface implémenté par ce type valeur. La boxe d’un type valeur alloue une instance d’objet sur le tas et copie la valeur dans le nouvel objet.
Considérez la déclaration suivante d’une variable de type valeur :
int i = 123;
L’instruction suivante applique implicitement l’opération de boxe sur la variable i
:
// Boxing copies the value of i into object o.
object o = i;
Le résultat de cette instruction est la création d’une référence o
d’objet , sur la pile, qui fait référence à une valeur du type int
, sur le tas. Cette valeur est une copie de la valeur de type valeur affectée à la variable i
. La différence entre les deux variables et o
, i
est illustrée dans l’image suivante de la conversion de boxe :
Il est également possible d’effectuer explicitement la boxe comme dans l’exemple suivant, mais la boxe explicite n’est jamais nécessaire :
int i = 123;
object o = (object)i; // explicit boxing
Exemple :
Cet exemple convertit une variable i
entière en objet o
à l’aide de la boxe. Ensuite, la valeur stockée dans la variable i
est remplacée par 123
456
. L’exemple montre que le type de valeur d’origine et l’objet boxed utilisent des emplacements de mémoire distincts et peuvent donc stocker différentes valeurs.
// 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
Déballage
Unboxing est une conversion explicite du type object
en type valeur ou d’un type d’interface vers un type valeur qui implémente l’interface. Une opération d’annulation de boîte de réception se compose des éléments suivants :
Vérification de l’instance d’objet pour vous assurer qu’il s’agit d’une valeur boxée du type valeur donné.
Copie de la valeur de l’instance dans la variable de type valeur.
Les instructions suivantes illustrent les opérations boxing et unboxing :
int i = 123; // a value type
object o = i; // boxing
int j = (int)o; // unboxing
La figure suivante illustre le résultat des instructions précédentes :
Pour que le déboxing des types valeur réussisse au moment de l’exécution, l’élément qui est unboxed doit être une référence à un objet qui a été créé précédemment en boxant une instance de ce type valeur. La tentative d’annulation de la boîte de réception null
provoque un NullReferenceException. La tentative d’annulation de la boîte de réception d’une référence à un type valeur incompatible provoque un InvalidCastException.
Exemple :
L’exemple suivant illustre un cas d’unboxing non valide et du résultat InvalidCastException
. Utilisation try
et catch
, un message d’erreur s’affiche lorsque l’erreur se produit.
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.");
}
}
}
Ce programme génère les résultats suivants :
Specified cast is not valid. Error: Incorrect unboxing.
Si vous modifiez l’instruction :
int j = (short)o;
vers :
int j = (int)o;
la conversion est effectuée et vous obtiendrez la sortie :
Unboxing OK.
Spécification du langage C#
Pour plus d'informations, voir la spécification du langage C#. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.