OpCodes.Readonly Feld

Definition

Gibt an, dass der nachfolgende Arrayadressenvorgang zur Laufzeit keine Typüberprüfung durchführt und einen verwalteten Zeiger zurückgibt, dessen Veränderbarkeit eingeschränkt ist.

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

Die folgende Tabelle enthält das Hexadezimal- und Microsoft MSIL-Assemblyformat (Intermediate Language) der Anweisung sowie eine kurze Referenzzusammenfassung:

Format Assemblyformat Description
FE 1E readonly. Geben Sie an, dass der nachfolgende Arrayadressenvorgang zur Laufzeit keine Typüberprüfung durchführt und einen verwalteten Zeiger mit eingeschränkter Veränderbarkeit zurückgibt.

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

  1. Zur Laufzeit wird kein Typüberprüfungsvorgang ausgeführt. Beachten Sie, dass in der Regel eine implizite Typüberprüfung für die ldelema und stelem Anweisungen vorhanden ist, wenn sie für Referenztyparrays verwendet werden. Es gibt niemals eine Laufzeittypüberprüfung für Wertklassen. Dies ist also readonly ein no-op in diesem Fall.

  2. Der Prüfer behandelt das Ergebnis des Vorgangsadressen als verwalteter Zeiger mit eingeschränkter Änderbarkeit.

Der Zeiger wird als eingeschränkte Veränderbarkeit bezeichnet, da der definierende Typ steuert, ob der Wert stummgeschaltet werden kann. Bei 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 stellen die Klassen, die primitive Typen (z. B. System.Int32) darstellen, keine Mutatoren offen 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 ldfld, ldflda, , stfld, calloderconstrained callvirt Anweisungen.

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

  • source Als Parameter für die cpobj Anweisung.

Alle anderen Vorgänge sind unzulässig, einschließlich der stobjAnweisungen initobjoder mkrefanystind Vorgänge.

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(), in dem der Elementtyp des Arrays arr ein generischer Typ ist, der auf eine Schnittstelle mit der Methode mbeschränkt wurde, möglicherweise 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 Typüberprüfung ist nicht nur ineffizient, sondern semantisch falsch. Die Typüberprüfung ldelema ist eine genaue Übereinstimmung, die zu stark ist. Wenn das Array Unterklassen vom Typ !0 enthält, schlägt der obige Code die Typprüfung fehl.

Die Adresse des Arrayelements wird anstelle des Elements selbst abgerufen, um ein Handle für arr[i] dies sowohl für Werttypen als auch für Verweistypen zu haben, und somit 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 Referenztyps enthält. Um sicher zu sein, müssen Sie sicherstellen, dass keine Änderungen an dem Array über diesen Zeiger vorgenommen werden. Die Prüfregeln stellen dies sicher. Der eingeschränkte verwaltete Zeiger kann als Objekt von Instanzmethodenaufrufen übergeben werden, daher ist er nicht streng schreibgeschützt für Werttypen, es gibt jedoch kein Typsicherheitsproblem für Werttypen.

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

Gilt für: