83 votes

Occurrence de boxe en c#

Je suis en train de collecter toutes les situations dans lesquelles la boxe se produit en C#:

  • La conversion de tout type de valeur de System.Object type:

    struct S { }
    object box = new S();
    
  • La conversion de tout type de valeur de System.ValueType type:

    struct S { }
    System.ValueType box = new S();
    
  • La conversion de tout type énumération de System.Enum type:

    enum E { A }
    System.Enum box = E.A;
    
  • La conversion de tout type de valeur dans l'interface de référence:

    interface I { }
    struct S : I { }
    I box = new S();
    
  • Non-valeur de la constante de types en C# concaténation de chaîne:

    char c = F();
    string s1 = "char value will box" + c;
    
  • La création de délégué de la valeur type méthode d'instance:

    struct S { public void M() {} }
    Action box = new S().M;
    
  • L'appel de la non-substituée méthodes virtuelles sur des types de valeur:

    enum E { A }
    E.A.GetHashCode();
    
  • Les paramètres facultatifs de object type avec le type de valeur valeurs par défaut:

    void M([Optional, DefaultParameterValue(42)] object o);
    M(); // boxing at call-site
    

Sont-il plus de cas de la boxe, peut-être caché, que vous connaissez?

41voto

Motti Shaked Points 864

C'est une excellente question!

La boxe se produit exactement pour la raison suivante: lorsque nous avons besoin d'une référence à un type de valeur. Tout ce que vous avez énumérés, appartient à cette règle.

Par exemple, puisque l'objet est un type de référence, la conversion d'une valeur de type d'objet nécessite une référence à un type de valeur, ce qui provoque la boxe.

Si vous souhaitez la liste de tous les scénarios possibles, vous devez également inclure les produits dérivés, tels que les retournant une valeur de type à partir d'une méthode qui renvoie un objet ou un type d'interface, car cela jette automatiquement le type de la valeur de l'objet ou de l'interface.

Par ailleurs, la concaténation de chaîne le cas où vous astucieusement identifié dérive aussi de la conversion en objet. L'opérateur + est traduite par le compilateur pour un appel à la méthode Concat de la chaîne, qui accepte un objet pour le type de valeur que vous passer, donc la conversion de l'objet et donc de boxe se produit.

Au fil des années, j'ai toujours conseillé aux développeurs de se rappeler la raison de la boxe (j'ai précisé ci-dessus) au lieu de mémoriser tous les cas, parce que la liste est longue et difficile à retenir. Cela favorise aussi la compréhension de ce qu'IL code, le compilateur génère pour notre code C# (par exemple + sur la chaîne entraîne un appel à la Chaîne.Concat). Lorsque votre e dans le doute sur ce que le compilateur génère et si de la boxe se produit, vous pouvez utiliser IL Désassembleur (ILDASM.exe). En général, vous devriez regarder pour la zone opcode (il y a un seul cas où la boxe pourrait se produire même si IL ne comprend pas la zone de l'opcode, plus de détails ci-dessous).

Mais je suis d'accord que certains de boxe occurrences sont moins évidentes. Vous énumérées l'une d'entre elles: l'appel d'une non-méthode de remplacement d'un type valeur. En fait, c'est moins évident pour une autre raison: lorsque vous vérifiez le code IL vous ne voyez pas la boîte de opcode, mais la contrainte de l'opcode, de sorte que même dans le IL il n'est pas évident que la boxe qui se passe! Je ne rentrerai pas dans les détails pourquoi pour éviter cette réponse de devenir encore plus longtemps...

Un autre cas pour le moins évident, la boxe est lors de l'appel d'une méthode de classe de base d'une structure. Exemple:

struct MyValType
{
    public override string ToString()
    {
        return base.ToString();
    }
}

Ici ToString est remplacée, donc appeler ToString sur MyValType ne génère pas de la boxe. Cependant, la mise en œuvre des appels à la base de ToString et que les causes de boxe (vérifier l'IL!).

Par ailleurs, ces deux non-évident de boxe scénarios proviennent également de la règle ci-dessus. Lorsqu'une méthode est appelée sur la classe de base d'un type de valeur, il doit y avoir quelque chose pour ce mot-clé de référence. Depuis la classe de base d'un type de valeur est (toujours) un type de référence, ce mot-clé doit se référer à un type de référence, et donc nous avons besoin d'une référence à un type de valeur et donc de boxe se produit en raison de la règle unique.

Voici un lien direct vers l'article de mon en ligne .NET cours qui traite de la boxe dans le détail: http://motti.me/mq

Si vous êtes uniquement intéressé par plus avancé de boxe scénarios voici un lien direct (si le lien ci-dessus vous y emmène ainsi une fois qu'il aborde le plus de trucs de base): http://motti.me/mu

J'espère que cela aide!

Motti

5voto

Viacheslav Ivanov Points 631

Appeler une méthode non virtuelle GetType() sur type de valeur :

3voto

nawfal Points 13500

Mentionné dans Motti de réponse, juste en les illustrant avec des exemples de code:

Les paramètres qui interviennent

public void Bla(object obj)
{

}

Bla(valueType)

public void Bla(IBla i) //where IBla is interface
{

}

Bla(valueType)

Mais c'est sûr:

public void Bla<T>(T obj) where T : IBla
{

}

Bla(valueType)

Le type de retour

public object Bla()
{
    return 1;
}

public IBla Bla() //IBla is an interface that 1 inherits
{
    return 1;
}

Vérification de la contrainte de T par rapport à null

public void Bla<T>(T obj)
{
    if (obj == null) //boxes.
}

L'utilisation de la dynamique

dynamic x = 42; (boxes)

Un autre

enumValue.HasFlag

0voto

Jesse C. Slicer Points 11750
<ul> <li>En utilisant les collections non génériques dans <code></code> tels que <code></code> ou <code></code> .</li> <p>Accordé, ce sont des instances spécifiques de votre première affaire, mais ils peuvent être des pièges cachés. C’est incroyable la quantité de code, j’ai rencontré encore aujourd'hui qui utilisent ces au lieu de <code></code> et <code></code> .</p></ul>

0voto

sll Points 30638

L’ajout de toute valeur de type de valeur dans ArrayList entraîne la boxe :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X