Box et Unbox qu'est-ce que cela signifie? [dupliquer]
Question
Doublons possibles: Pourquoi avons-nous besoin de boxe et unboxing en C #?
Qu'est-ce que la boxe et unboxing et quels sont le commerce offs
En C # ce que signifie assis doe: "Boîte et Unbox"
Voici un extrait de MSDN où je le texte fondé.
Mais cette commodité a un coût. Tout type de référence ou une valeur qui est ajouté à un ArrayList est implicitement upcast à l'objet. Si les articles sont types de valeur, ils doivent être mis en boîte quand ils sont ajoutés à la liste, et Unboxed quand ils sont récupérés. Tous les deux la coulée et la boxe et opérations unboxing diminuent performance; l'effet de la boxe et unboxing peut être très importante scénarios où vous devez itérer sur grandes collections.
Merci!
La solution
Voici une explication plus détaillée qui se penche sur l'interne de Common Language Runtime.
Tout d'abord, nous allons faire la différence entre les types valeur et types de référence :
- un type de valeur est maintenue sur le pile et une copie de celui-ci est transmis à des méthodes appelées
- Une valeur de référence est maintenue dans la gestion tas et la pile tient seulement un pointeur (référence) à son emplacement. L'emplacement, et non l'objet, est passé à des méthodes appelées
Si vous ne savez pas ce que la pile est (ne soyez pas offensés), il est une zone de mémoire qui contient les variables locales dans une méthode et adresses des fonctions de l'appelant utilisées pour l'enseignement de return
(juste pour être bref et fournir un général répondre). Lorsque vous appelez une méthode, une surface suffisante sur la pile est statiquement qui lui est attribué, de sorte que l'allocation de la pile est toujours appelée allocation statique.
Le tas, au contraire, est une zone de mémoire séparée de la pile, propriété du processus en cours d'exécution, dans lequel l'allocation doit être d'abord demandé au système d'exploitation, et c'est pourquoi il est appelé allocation dynamique (si vous ne courez pas dans une instruction if, par exemple, la mémoire ne peut être allouée pour votre processus, au lieu est toujours attribué la pile).
Il suffit de faire un dernier exemple de tas et de la pile: dans des langages tels que C ++, déclarant int[100] a;
alloue statiquement 100 * 8 octets sur la pile (système 64 bits pris), alors que int* a = new int[100];
déclare un 8 octets (64 bits systèmes) zone sur la pile et demande 800 plus d'octets sur le tas, si et le cas échéant.
Parlons-C # au sujet:
Boxe
Comme int est un type de valeur et est allouée sur la pile, lorsque vous lancez pour objet ou tout autre type de référence (en fait il n'y a pas d'autre type de référence à partir de laquelle int peut hériter, mais il est une règle générale) la valeur doit devenir nécessairement un type de référence. Ainsi, une nouvelle zone sur le tas est alloué, l'objet est boxed à l'intérieur et la pile contient un pointeur vers elle.
Unboxing
Juste le contraire: quand vous avez un type de référence, comme objet, et que vous voulez le jeter à un type de valeur, par exemple pour int, la nouvelle valeur doit être tenue sur la pile, donc CLR va tas, < em> un-boîtes la valeur et la copie dans la pile.
En d'autres termes
Souvenez-vous des exemples de int[]
et int*
? Simplement, quand vous avez int
en C #, le moteur d'exécution attend son emplacement de pile à maintenir la valeur mais quand vous avez object
, il attend sa valeur réelle d'être à l'emplacement du tas a par la pile.
Autres conseils
Il existe dans .NET Framework deux types différents.
types de valeur tel que int, double, simple
ReferenceTypes Liste des tableaux liste et beaucoup, beaucoup d'autres
Les variables de type types de valeur sont stockés dans la pile ReferenceTyped variables sont stockées dans tas
Les variables de type types de valeur stocker la valeur ReferenceTyped les variables stocker la référence à une valeur
donc si vous copiez un ValueType variable - il y a un copie réelle d'une valeur mais si vous copiez un referenceType variable -. vous obtiendrez un montant supplémentaire référence à la même variable
Boxe dans vos moyens d'interrogation, qu'une variable valueType (par exemple int) sera traité n'a pas aimé un type référence variable - .net donne dans une nouvelle boîte . Ainsi, il sera encapsulé dans le tas et il y aura référence (s) à elle.
Si vous souhaitez que la valeur soit à nouveau dans une variable valueType vous devez Unbox il (le sortir de la boîte). Ainsi, la valeur sera prise sur le tas -. Et stocké / à la pile une fois
magasins ArrayList objets uniquement. Pour un type de référence (comme String
) Aucun problème mais pour un ValueType (int, DateTime, ..) il est.
Ces types de valeur doivent être convertis à un objet avant de pouvoir les stocker sous forme d'objets plaine. Cette « conversion à l'objet » est appelé « la boxe » et prend un peu de temps.
Quand vous lisez le dos de la valeur, vous devez convertir l'objet à int
(ou quelque chose comme ça). Ceci est appelé "unboxing".