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 hexadezimale und Microsoft MSIL-Assemblyformat (Intermediate Language) der Anweisung zusammen mit einer kurzen Referenzzusammenfassung aufgeführt:

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

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

  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. Der Prüfer behandelt das Ergebnis des Adress-of-Vorgangs als verwalteten Zeiger mit eingeschränkter Veränderbarkeit.

Der Zeiger soll eine eingeschränkte Veränderlichkeit aufweisen, 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 Wert an Ort und Stelle 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 , ldflda, stfld, 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 stobjinitobj- oder mkrefany -Vorgänge oder einer der stind Anweisungen.

Der Zweck des readonly Präfixes besteht darin, beim Abrufen eines Elements aus einem Array im generischen Code eine Typprüfung 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 führt die ldelema Anweisung eine Typüberprüfung für den Fall durch, dass !0 ein Verweistyp ist. Diese Typprüfung ist nicht nur ineffizient, sondern 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 die Typüberprüfung im obigen Code 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 Laufzeitprüfung zu überspringen, wenn das Array Elemente eines Verweistyps enthält. Um sicher zu sein, muss sichergestellt werden, dass über diesen Zeiger keine Änderungen am Array vorgenommen werden. Dies wird durch die Überprüfungsregeln sichergestellt. Der eingeschränkte verwaltete Zeiger kann als Objekt von Instanzmethodenaufrufen übergeben werden, daher ist er streng genommen nicht schreibgeschützt für Werttypen, aber es gibt kein Typsicherheitsproblem für Werttypen.

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

Gilt für: