Domanda

Stavo solo partecipando alla domanda Stack Overflow È tutto in .NET un obiettare? .

E un poster (nei commenti della risposta accettata) sembrava pensare che l'esecuzione di una chiamata del metodo su un tipo di valore causasse un inscatolamento. Mi ha indicato Boxing and Unboxing (Programmazione C # Guida) che non specifica esattamente il caso d'uso che stiamo descrivendo.

Non sono uno che si fida di una singola fonte, quindi volevo solo ottenere ulteriori feedback sulla domanda. La mia intuizione è che non c'è boxe ma la mia intuizione fa schifo. : D

Per elaborare ulteriormente:

L'esempio che ho usato era:

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

La boxe non si verifica se la struttura in questione sovrascrive il metodo ereditato dall'oggetto come afferma la risposta accettata qui.

Tuttavia, se la struttura non sostituisce il metodo, un "vincolo" Il comando CIL viene eseguito prima di una chiamata. Secondo la documentazione, OpCodes. Campo vincolato , questo si traduce in boxe :

  

Se thisType è un tipo di valore e   thisType non implementa il metodo   quindi ptr è dereferenziato, inscatolato e   passato come puntatore "questo" a   istruzione del metodo callvirt.

È stato utile?

Soluzione

Ecco l'IL per il tuo codice:

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

Quindi la risposta in questo caso è no.

Altri suggerimenti

Nel caso in cui tu abbia dato la risposta è no, come ha sottolineato lo zoccolo.

Tuttavia, lo farà se si chiama un metodo tramite un puntatore all'interfaccia.

Considera il codice:

interface IZot
{
    int F();
}

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

Poi

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

non si traduce in 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 

Tuttavia, ciò fa:

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

  

" Credo che chiamando ToString,   Risultati uguali e Gethashcode   boxe se la struttura no   sovrascrivere i metodi. "

Ho controllato ToString per te. Int32 ignora ToString, quindi ho creato una struttura che non lo fa. Ho usato .NET Reflector per assicurarmi che la struttura non fosse in qualche modo magicamente dominante su ToString () e non lo era.

Quindi il codice era così:

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 MSIL (tramite ILDASM ) per il metodo principale è questo:

  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

Ora, nonostante non avvenga alcuna chiamata di boxe, se si seleziona la documentazione su un vincolato + un virt virt , troverete che afferma che la boxe ha luogo. oOo

Quote:

  

Se thisType è un tipo di valore e   thisType non implementa il metodo   quindi ptr è dereferenziato, inscatolato e   passato come puntatore "questo" a   istruzione del metodo callvirt.

Credo che chiamare ToString, Equals e Gethashcode comporti un inscatolamento se la struttura non sovrascrive i metodi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top