Frage

ich beteiligt war gerade in Stack Overflow Frage Ist alles in .NET ein Objekt? .

Und ein Plakat (in den Kommentaren der akzeptierten Antwort) schien zu denken, dass ein Methodenaufruf auf einem Werttyp Durchführung im Boxen geführt. Er wies mich auf Boxen und Unboxing (C # Programmierung Guide) , die nicht genau den Anwendungsfall geben wir beschreiben.

Ich bin nicht einer eine einzige Quelle zu vertrauen, so wollte ich nur weiter Feedback über die Frage bekommen. Meine Intuition ist, dass es keine Boxen, aber meine Intuition nicht saugen. : D

Zur weiteren Ausarbeitung:

Das Beispiel I verwendet wurde:

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

Boxen tun nicht auftreten, wenn die Struktur in Frage die Methode aus dem Objekt geerbt hat Vorrang als die akzeptierte Antwort hier heißt es.

Allerdings, wenn die Struktur nicht die Methode nicht außer Kraft setzen, ein „einschränken“ CIL Befehls wird vor einer callvirt ausgeführt. Gemäß der Dokumentation, OpCodes. Constrained Feld , dies führt im Boxen :

  

Wenn thisType ein Werttyp und   thisType nicht Methode implementieren   dann ptr dereferenziert, geboxt, und   als ‚dieses‘ Zeiger auf den übergebenen   callvirt Methode Anweisung.

War es hilfreich?

Lösung

Hier ist die IL-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

Die Antwort ist in diesem Fall nicht.

Andere Tipps

Im Fall, dass Sie die Antwort gegeben haben, ist nicht, wie Sockel aufgezeigt.

Es wird jedoch, wenn Sie eine Methode über eine Schnittstelle Zeiger aufrufen.

Betrachten Sie den Code ein:

interface IZot
{
    int F();
}

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

Dann

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

Does nicht Ergebnis im Boxen:

.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 

Dies schließt jedoch:

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

  

"Ich glaube, dass ToString nennen,   Equals und GetHashCode Ergebnis in   Boxen, wenn die Struktur nicht   überschreiben die Methoden. "

Ich habe für Sie überprüft ToString. Int32 tut ToString außer Kraft setzen, so habe ich eine Struktur, die nicht der Fall ist. Ich verwendete .NET Reflector , um sicherzustellen, dass die Struktur wurde nicht irgendwie magisch ToString überschreiben () und es war nicht.

So ist der Code wie folgt war:

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

Und die MSIL (via ILDASM ) für die Main-Methode ist folgende:

  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

Nun, obwohl es keine Boxen Anruf stattfindet, wenn man a href überprüfen <= "http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.constrained.aspx" rel = „nofollow noreferrer“> die Dokumentation über einen eingeschränkten + einen Anruf virt , werden Sie feststellen, es heißt, dass Boxen stattfindet. oOo

Zitat:

  

Wenn thisType ein Werttyp und   thisType nicht Methode implementieren   dann ptr dereferenziert, geboxt, und   als ‚dieses‘ Zeiger auf den übergebenen   callvirt Methode Anweisung.

Ich glaube, dass ToString Aufruf Equals und GetHashCode Ergebnis im Boxen, wenn die Struktur überschreibt nicht die Methoden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top