2010-11-18 28 views
2

Compte tenu de cette classe:Est-ce qu'un ValueType est encadré lorsqu'il est déclaré comme faisant partie d'une classe?

public class Foo 
{ 
    public Int32 MyField; 
} 

Je suppose que le membre « MyField » n'est pas sur la pile de fil parce qu'il pourrait être accessible par plusieurs threads, il doit être sans aucun doute dans le tas managé, mais le fait que cela signifie il est emballé et déballé à chaque fois qu'il est utilisé?

Merci à l'avance

+0

merci à tous! – vtortola

+0

Je pense que de nombreuses explications sur la façon dont les types de valeur diffèrent des types de référence peuvent induire le lecteur en erreur, car ils ont tendance à dire qu'il existe des types de valeur sur la pile; ce qui n'est vraiment le cas que si vous parlez de variables de type valeur déclarées dans une méthode. Je pensais que la réponse de James Curran avait une bonne suggestion d'utiliser les termes "Over Here" et "Over There" pour décrire l'emplacement de la mémoire allouée pour un objet plutôt que "Dans la pile" et "Dans le tas": http://stackoverflow.com/questions/3790436/where-are-value-types-stored-in-c-generic-collections/3790468#3790468 –

+0

Et même lorsqu'une variable de type valeur est déclarée dans une méthode, elle peut être déplacée vers la tas pour un certain nombre de raisons. Voir «La vérité sur les types de valeur» d'Eric Lippert. http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx –

Répondre

8

Non, il n'est pas encadré à chaque fois qu'il est utilisé. La boxe se produit uniquement lorsque vous forcez un type de valeur dans un type de référence - cela n'a vraiment rien à voir avec l'allocation de la mémoire réelle pour la valeur (ou même si de la mémoire a été allouée).

Dans votre cas, c'est votre façon d'agir sur MyField qui détermine si elle est encadrée, et non comment Foo est traitée.

//No Boxing 
    var f = new Foo(); 
    f.MyField = 5; 
    int val = f.MyField; 


    //Boxing 
    var f = new Foo(); 
    f.MyFIeld = 5; 
    object val = f.MyField; 

Notez que dans le second exemple val contient maintenant une référence à un int boxed. MyField est encore (et restera toujours) un Unboxed int et peut être consulté sans unboxing (Merci de remarquer la clarification nécessaire, LukeH)

+2

Il convient de souligner que dans votre deuxième exemple, la variable 'val' est la boîte' int'; 'MyField' lui-même n'est jamais encadré. – LukeH

2

Non, le type de valeur ne sont pas mis en boîte.

La boxe se produit uniquement lorsque vous utilisez un type de valeur comme s'il s'agissait d'un objet, par exemple lors du stockage d'un int dans un tableau de object. C'est-à-dire:

object[] a = new object[10]; 
int x = 1; 
a[0] = x; 

Dans ce cas, le type de valeur est encadré.

Mais un type de valeur stocké en tant que champ à l'intérieur d'une classe n'est pas encadré.

2

Non, la boxe ne se produit lorsque est traité un type de valeur en tant que System.Object (généralement par moulage implicite, c'est-à-dire en le passant comme paramètre de méthode)

1

Les types de valeurs ne sont encadrés que lorsqu'ils sont affectés à une variable de type référence (par exemple object). Si vous n'attribuez jamais MyField à autre chose qu'un int ou une autre structure à laquelle il peut être cast (par exemple double), il ne sera jamais encadré.