Pergunta

Eu estava apenas participando em questão Stack Overflow Está tudo em .NET um objeto? .

E um cartaz (em comentários de resposta aceita) parecia pensar que a realização de uma chamada de método em um tipo de valor resultou no boxe. Ele apontou-me a Boxing e Unboxing (C # Programming guia) , que não especifica exatamente o caso de uso que estamos descrevendo.

Eu não sou um para confiar em uma única fonte, então eu só queria obter mais feedback sobre a questão. Minha intuição é que não há nenhuma boxe, mas minha intuição é que chupar. : D

Para elaborar mais:

O exemplo que eu usei foi:

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

Boxe faz não ocorrer se a estrutura em questão substitui o método herdadas do objeto como a resposta aceito aqui afirma.

No entanto, se a estrutura não substitui o método, um "constrangimento" CIL comando é executado antes de uma callvirt. De acordo com a documentação, OpCodes. Constrained campo , isso resulta em boxe :

Se thisType é um tipo de valor e thisType não implementar o método então ptr é referência, encaixotado, e transmitido como o 'esta' ponteiro para o instrução método callvirt.

Foi útil?

Solução

Aqui está o IL para o seu código:

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

Portanto, a resposta, neste caso, não é.

Outras dicas

No caso de ter dado a resposta é não, como plinto apontou.

No entanto, ele vai se chamar um método através de um ponteiro interface.

Considere o código:

interface IZot
{
    int F();
}

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

Em seguida

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

O não resultado no 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 

No entanto, isso faz:

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

   .locals init (
        [0] class ConsoleApplication1.IZot z,
        [1] valuetype ConsoleApplication1.Zot CS$0$0000)
    L_0000: nop 
    L_0001: ldloca.s CS$0$0000
    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

"Eu acredito que chamar ToString, É igual e resultado GetHashCode em boxe, se a estrutura não faz substituir os métodos. "

Eu verifiquei ToString para você. Int32 faz override ToString, por isso fiz um struct que não. Eu costumava .NET Reflector para garantir que a estrutura não foi magicamente substituindo ToString () , e não foi.

Assim, o código foi assim:

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;
            }
        }
    }
}

E a MSIL (via ILDASM ) para o método principal é esta:

  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

Agora, apesar de nenhuma chamada de boxe tomada lugar, se você verificar a documentação sobre um restrito + uma chamada virt , você vai encontrá-lo afirma que o boxe tem lugar. oOo

Citação:

Se thisType é um tipo de valor e thisType não implementar o método então ptr é referência, encaixotado, e transmitido como o 'esta' ponteiro para o instrução método callvirt.

Eu acredito que chamar ToString, iguais e resultado GetHashCode no boxe, se a estrutura não substitui os métodos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top