Teilen über


OpCodes.Readonly Feld

Definition

Gibt an, dass beim nachfolgenden Vorgang zur Arrayadresse zur Laufzeit keine Typüberprüfung durchgeführt wird und dass ein verwalteter Zeiger zurückgegeben wird, der nur bedingt geändert werden kann.

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

Feldwert

Hinweise

In der folgenden Tabelle sind das Hexadezimal- und MSIL-Assemblyformat (Microsoft Intermediate Language) der Anweisung sowie eine kurze Referenzzusammenfassung aufgeführt:

Format Assemblyformat BESCHREIBUNG
FE 1E readonly. Geben Sie an, dass der nachfolgende Arrayadressvorgang zur Laufzeit keine Typüberprüfung durchführt und dass ein verwalteter Zeiger mit eingeschränkter Veränderlichkeit zurückgegeben wird.

Dieses Präfix kann nur unmittelbar vor der ldelema Anweisung und aufrufen der speziellen Address Methode für Arrays angezeigt werden. Seine Auswirkungen auf den nachfolgenden Vorgang sind zwei:

  1. Zur Laufzeit wird kein Typüberprüfungsvorgang ausgeführt. Beachten Sie, dass es normalerweise eine implizite Typüberprüfung für die ldelema Anweisungen und stelem gibt, wenn sie für Verweistyparrays verwendet werden. Es gibt nie eine Laufzeittypüberprüfung für Wertklassen, daher readonly ist in diesem Fall ein No-Op.

  2. Die Überprüfung behandelt das Ergebnis des Address-of-Vorgangs als verwalteten Zeiger mit eingeschränkter Veränderlichkeit.

Der Zeiger weist eine eingeschränkte Veränderlichkeit auf, da der definierende Typ steuert, ob der Wert mutiert werden kann. Für Wertklassen, die keine öffentlichen Felder oder Methoden verfügbar machen, die den Aktuellen Wert aktualisieren, ist der Zeiger schreibgeschützt (daher der Name des Präfixes). Insbesondere die Klassen, die primitive Typen darstellen (z. B. System.Int32), machen keine Mutatoren verfügbar und sind daher schreibgeschützt.

Ein verwalteter Zeiger, der auf diese Weise eingeschränkt ist, kann nur auf folgende Weise verwendet werden:

  • object Als Parameter für die ldfldAnweisungen , ldfldastfld, , calloderconstrained callvirt.

  • pointer Als Parameter für die ldobj -Anweisung oder eine der ldind Anweisungen.

  • source Als Parameter für die cpobj -Anweisung.

Alle anderen Vorgänge, die nicht zulässig sind, einschließlich der stobj-, initobj- oder mkrefany -Vorgänge oder einer der stind Anweisungen.

Der Zweck des readonly Präfixes besteht darin, eine Typüberprüfung beim Abrufen eines Elements aus einem Array im generischen Code zu vermeiden. Beispielsweise kann der Ausdruck arr[i].m(), bei dem der Elementtyp des Arrays arr ein generischer Typ ist, der auf eine Schnittstelle mit der -Methode mbeschränkt wurde, in die folgende MSIL kompiliert werden.

ldloc arr  
ldloc i  
readonly.  
ldelema !0    // Loads the pointer to the object.  
…             // Load the arguments to the call.  
constrained. !0  
callvirt m  

Ohne das readonly Präfix würde die ldelema Anweisung eine Typüberprüfung durchführen, wenn !0 ein Verweistyp war. Diese Typprüfung ist nicht nur ineffizient, sondern auch semantisch falsch. Die Typprüfung für ldelema ist eine genaue Übereinstimmung, die zu stark ist. Wenn das Array Unterklassen des Typs !0 enthält, schlägt der obige Code die Typüberprüfung fehl.

Die Adresse des Arrayelements wird anstelle des Elements selbst abgerufen, um ein Handle für arr[i] zu erhalten, das sowohl für Werttypen als auch für Verweistypen funktioniert und daher an die constrained callvirt -Anweisung übergeben werden kann.

Im Allgemeinen wäre es unsicher, die Laufzeitüberprüfung zu überspringen, wenn das Array Elemente eines Verweistyps enthält. Um sicher zu sein, muss sichergestellt werden, dass keine Änderungen am Array über diesen Zeiger vorgenommen werden. Die Prüfregeln stellen dies sicher. Der eingeschränkte verwaltete Zeiger kann als Objekt von instance Methodenaufrufen übergeben werden, sodass er streng genommen nicht schreibgeschützt für Werttypen ist, aber es gibt kein Typsicherheitsproblem für Werttypen.

Die folgende Emit Methodenüberladung kann den readonly Opcode verwenden:

Gilt für: