OpCodes.Readonly Feld
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
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:
Zur Laufzeit wird kein Typüberprüfungsvorgang ausgeführt. Beachten Sie, dass es normalerweise eine implizite Typüberprüfung für die
ldelema
Anweisungen undstelem
gibt, wenn sie für Verweistyparrays verwendet werden. Es gibt nie eine Laufzeittypüberprüfung für Wertklassen, daherreadonly
ist in diesem Fall ein No-Op.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 dieldfld
Anweisungen ,ldflda
stfld
, ,call
oderconstrained callvirt
.pointer
Als Parameter für dieldobj
-Anweisung oder eine derldind
Anweisungen.source
Als Parameter für diecpobj
-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 m
beschrä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: