OpCodes.Constrained Feld

Definition

Schränkt den Typ ein, für den eine virtuelle Methode aufgerufen wird.

public: static initonly System::Reflection::Emit::OpCode Constrained;
public static readonly System.Reflection.Emit.OpCode Constrained;
 staticval mutable Constrained : System.Reflection.Emit.OpCode
Public Shared ReadOnly Constrained As OpCode 

Feldwert

Hinweise

In der folgenden Tabelle sind das Hexadezimal- und MSIL-Assemblyformat (Microsoft Intermediate Language) der Anweisung zusammen mit einer kurzen Referenzzusammenfassung aufgeführt:

Format Assemblyformat BESCHREIBUNG
FE 16 <T> Eingeschränkt. thisType Rufen Sie eine virtuelle Methode für einen Typ auf, der auf den Typ Tbeschränkt ist.

Das constrained Präfix ist nur für eine callvirt Anweisung zulässig.

Der Zustand des MSIL-Stapels muss an diesem Punkt wie folgt aussehen:

  1. Ein verwalteter Zeiger, ptr, wird auf den Stapel gepusht. Der Typ von ptr muss ein verwalteter Zeiger (&) auf thisTypesein. Beachten Sie, dass sich dies von dem Fall einer nicht vorfixierten callvirt Anweisung unterscheidet, die einen Verweis auf thisTypeerwartet.

  2. Methodenargumente arg1 werden argN wie bei einer nicht vorfixierten Anweisung auf den Stapel gepusht callvirt .

Das constrained Präfix ist so konzipiert, dass callvirt Anweisungen unabhängig davon, ob thisType es sich um einen Werttyp oder einen Verweistyp handelt, einheitlich gemacht werden können.

Wenn eine callvirtmethod Anweisung mit constrainedthisTypepräfixiert wurde, wird die Anweisung wie folgt ausgeführt:

  • Wenn thisType ein Verweistyp (im Gegensatz zu einem Werttyp) ist, ptr wird dereferenced und als "this"-Zeiger auf den callvirt von methodübergeben.

  • Wenn thisType ein Werttyp ist und thisType implementiert ptrmethod wird, wird unmodifiziert als "this"-Zeiger auf eine callmethod Anweisung für die Implementierung von methodthisTypeübergeben.

  • Wenn thisType es sich um einen Werttyp handelt und thisType nicht implementiert ptrmethod wird, wird dereferenced, boxed und als "this"-Zeiger auf die callvirtmethod Anweisung übergeben.

Dieser letzte Fall kann nur auftreten, wenn method für Object, ValueTypeoder Enum definiert und nicht von überschrieben wurde thisType. In diesem Fall bewirkt das Boxing, dass eine Kopie des ursprünglichen Objekts erstellt wird. Da jedoch keine der Methoden von Object, ValueTypeund Enum den Zustand des Objekts ändert, kann diese Tatsache nicht erkannt werden.

Das constrained Präfix unterstützt IL-Generatoren, die generischen Code erstellen. Normalerweise ist die callvirt Anweisung für Werttypen ungültig. Stattdessen ist es erforderlich, dass IL-Compiler die oben beschriebene Transformation "diese" zur Kompilierzeit effektiv ausführen, abhängig vom ptr Typ und der aufgerufenen Methode. Wenn ptr es sich jedoch um einen generischen Typ handelt, der zur Kompilierzeit unbekannt ist, ist es nicht möglich, diese Transformation zur Kompilierzeit durchzuführen.

Mit constrained opcode können IL-Compiler eine virtuelle Funktion auf einheitliche Weise aufrufen, unabhängig davon, ob ptr es sich um einen Werttyp oder einen Verweistyp handelt. Obwohl es für den Fall vorgesehen ist, dass thisType es sich um eine generische Typvariable handelt, funktioniert das constrained Präfix auch für nichtgenerische Typen und kann die Komplexität der Generierung virtueller Aufrufe in Sprachen verringern, die die Unterscheidung zwischen Werttypen und Verweistypen ausblenden.

Die Verwendung des constrained Präfixes vermeidet auch potenzielle Versionsverwaltungsprobleme bei Werttypen. Wenn das constrained Präfix nicht verwendet wird, muss eine andere IL ausgegeben werden, je nachdem, ob ein Werttyp eine Methode von System.Object überschreibt oder nicht. Wenn beispielsweise ein Werttyp V die Object.ToString()-Methode außer Kraft setzt, wird eine callV.ToString() Anweisung ausgegeben. Andernfalls werden eine box Anweisung und eine callvirtObject.ToString() Anweisung ausgegeben. Ein Versionsverwaltungsproblem kann im ersten Fall auftreten, wenn die Überschreibung später entfernt wird, und im letzteren Fall, wenn später eine Überschreibung hinzugefügt wird.

Das constrained Präfix kann auch für den Aufruf von Schnittstellenmethoden für Werttypen verwendet werden, da die Werttypmethode, die die Schnittstellenmethode implementiert, mithilfe von MethodImplgeändert werden kann. Wenn das constrained Präfix nicht verwendet wird, wird der Compiler gezwungen, die Methoden des Werttyps auszuwählen, an die zur Kompilierzeit gebunden werden soll. Die Verwendung des constrained Präfixes ermöglicht es dem MSIL, an die Methode zu binden, die die Schnittstellenmethode zur Laufzeit implementiert, anstatt zur Kompilierzeit.

Die folgende Emit Methodenüberladung kann den constrained opcode verwenden:

Gilt für: