Question

Je ne faisais que participer à la question Stack Overflow Tout est-il en .NET? objet? .

Et une affiche (dans les commentaires de la réponse acceptée) semblait penser que l'exécution d'un appel de méthode sur un type de valeur entraînait la boxe. Il m’a dirigé vers Boxing et Unboxing (programmation en C #) Guide) qui ne spécifie pas exactement le cas d'utilisation que nous décrivons.

Je ne suis pas du genre à faire confiance à une source unique, alors je voulais simplement obtenir de plus amples commentaires sur la question. Mon intuition est qu'il n'y a pas de boxe mais mon intuition est nulle. : D

Pour en savoir plus:

L'exemple que j'ai utilisé était:

int x = 5;
string s = x.ToString(); // Boxing??

La boxe ne se produit pas si la structure en question redéfinit la méthode héritée de l'objet comme l'indique la réponse acceptée ici.

Cependant, si la structure ne remplace pas la méthode, un "contraindre" La commande CIL est exécutée avant un callvirt. Selon la documentation, OpCodes. Champ contraint , cela entraîne la boxe :

  

Si thisType est un type valeur et   thisType n'implémente pas la méthode   puis ptr est déréférencé, mis en boîte et   passé comme le pointeur 'this' à la   instruction de méthode callvirt.

Était-ce utile?

La solution

Voici l'IL pour votre code:

L_0001: ldc.i4.5      // get a 5 on the stack
L_0002: stloc.0       // store into x
L_0003: ldloca.s x    // get the address of x on the stack
L_0005: call instance string [mscorlib]System.Int32::ToString()  // ToString
L_000a: stloc.1       // store in s

Donc, dans ce cas, la réponse est non.

Autres conseils

Dans le cas où vous avez répondu, non, comme l'a souligné le socle.

Cependant, cela sera le cas si vous appelez une méthode via un pointeur d'interface.

Considérez le code:

interface IZot
{
    int F();
}

struct Zot : IZot
{
    public int F()
    {
        return 123;
    }
}

Alors

Zot z = new Zot();
z.F();

Ne pas n'entraîne-t-il pas la boxe:

.locals init (
    [0] valuetype ConsoleApplication1.Zot z)
L_0000: nop 
L_0001: ldloca.s z
L_0003: initobj ConsoleApplication1.Zot
L_0009: ldloca.s z
L_000b: call instance int32 ConsoleApplication1.Zot::F()
L_0010: pop 
L_0011: ret 

Cependant, cela:

IZot z = new Zot();
z.F();

   .locals init (
        [0] class ConsoleApplication1.IZot z,
        [1] valuetype ConsoleApplication1.Zot CS<*><*>)
    L_0000: nop 
    L_0001: ldloca.s CS<*><*>
    L_0003: initobj ConsoleApplication1.Zot
    L_0009: ldloc.1 
    L_000a: box ConsoleApplication1.Zot
    L_000f: stloc.0 
    L_0010: ldloc.0 
    L_0011: callvirt instance int32 ConsoleApplication1.IZot::F()
    L_0016: pop 

@ ggf31316

  

"Je crois que l'appel de ToString,   Equals et Gethashcode résultent en   boxe si la structure ne   remplacer les méthodes. "

J'ai vérifié ToString pour vous. Int32 remplace ToString, alors j'ai créé une structure qui ne le fait pas. J'ai utilisé .NET Reflector pour m'assurer que la structure ne remplaçait pas magiquement ToString (). et ce ne fut pas le cas.

Le code ressemblait à ceci:

using System;

namespace ConsoleApplication29
{
    class Program
    {
        static void Main(string[] args)
        {
            MyStruct ms = new MyStruct(5);
            string s = ms.ToString();
            Console.WriteLine(s);
        }
    }

    struct MyStruct
    {
        private int m_SomeInt;

        public MyStruct(int someInt)
        {
            m_SomeInt = someInt;
        }

        public int SomeInt
        {
            get
            {
                return m_SomeInt;
            }
        }
    }
}

Et le MSIL (via ILDASM ) pour la méthode Main est la suivante:

  IL_0000:  ldloca.s   ms
  IL_0002:  ldc.i4.5
  IL_0003:  call       instance void ConsoleApplication29.MyStruct::.ctor(int32)
  IL_0008:  ldloca.s   ms
  IL_000a:  constrained. ConsoleApplication29.MyStruct
  IL_0010:  callvirt   instance string [mscorlib]System.Object::ToString()
  IL_0015:  stloc.1
  IL_0016:  ldloc.1
  IL_0017:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_001c:  ret

Maintenant, malgré l'absence d'appel de boxe, si vous cochez la documentation sur un contraint + un appel virt , vous constaterez qu'il est écrit que la boxe a lieu. oOo

Citation:

  

Si thisType est un type valeur et   thisType n'implémente pas la méthode   puis ptr est déréférencé, mis en boîte et   passé comme le pointeur 'this' à la   instruction de méthode callvirt.

Je crois que l'appel de ToString, Equals et Gethashcode aboutit à une boxe si la structure ne remplace pas les méthodes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top