OpCodes.Readonly フィールド
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
以降の配列アドレス演算で、実行時に型チェックを実行しないこと、および変更可能性が制限されたマネージド ポインターを返すことを指定します。
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
フィールド値
注釈
次の表に、命令の 16 進数および Microsoft 中間言語 (MSIL) アセンブリ形式と、簡単な参照の概要を示します。
形式 | アセンブリ形式 | 説明 |
---|---|---|
FE 1E | Readonly。 | 後続の配列アドレス操作が実行時に型チェックを実行せず、変更可能性が制限されたマネージド ポインターを返すように指定します。 |
このプレフィックスは、命令の ldelema
直前にのみ出現し、配列の特殊な Address
メソッドを呼び出します。 後続の操作に対するその影響は次の 2 つです。
実行時に、型チェック操作は実行されません。 参照型配列で使用される場合、通常、 および
stelem
命令には暗黙的な型チェックldelema
があることに注意してください。 値クラスには実行時の型チェックがないため、readonly
その場合は操作なしです。検証ツールは、アドレスの操作の結果を、変更可能性が制限されたマネージド ポインターとして扱います。
ポインターは、値を変更できるかどうかを定義する型によって制御されるため、変更可能性が制限されると言われます。 値をインプレースで更新するパブリック フィールドまたはメソッドを公開しない値クラスの場合、ポインターは読み取り専用です (したがって、プレフィックスの名前)。 特に、プリミティブ型 (System.Int32 など) を表すクラスはミューテーターを公開しないため、読み取り専用です。
この方法で制限されたマネージド ポインターは、次の方法でのみ使用できます。
object
、call
ldflda
stfld
またはconstrained callvirt
命令のldfld
パラメーターとして指定します。命令または
pointer
命令のldind
1 つのパラメーターldobj
として。命令の
source
パラメーターcpobj
として。
その他のすべての操作 (、、、またはmkrefany
命令を含むstobj
initobj
) はstind
許可されていません。
プレフィックスのreadonly
目的は、ジェネリック コード内の配列から要素をフェッチするときにチェック型を回避することです。 たとえば、配列arr
の要素型が メソッドm
とのインターフェイスを持つよう制約されているジェネリック型である 式 arr[i].m()
は、次の MSIL にコンパイルされる可能性があります。
ldloc arr
ldloc i
readonly.
ldelema !0 // Loads the pointer to the object.
… // Load the arguments to the call.
constrained. !0
callvirt m
readonly
プレフィックスがない場合、ldelema
!0 が参照型の場合、命令は型チェックを実行します。 この型は非効率的チェックだけでなく、意味的には正しくありません。 にチェックldelema
型は完全一致であり、厳密すぎます。 配列が !0 型のサブクラスを保持している場合、上記のコードは型チェック失敗します。
配列要素のアドレスは、値型と参照型の両方で機能する のハンドル arr[i]
を持つために、要素自体の代わりにフェッチされるため、命令に constrained callvirt
渡すことができます。
一般に、配列が参照型の要素を保持している場合、実行時のチェックをスキップするのは安全ではありません。 安全にするために、このポインターを使用して配列に対する変更が行われないようにする必要があります。 検証ツールの規則でこれを確認します。 制限付きマネージド ポインターはインスタンス メソッド呼び出しのオブジェクトとして渡すことができるため、値型に対しては厳密には読み取り専用ではありませんが、値型に対する型セーフの問題はありません。
次 Emit のメソッド オーバーロードでは、オペコードを readonly
使用できます。
適用対象
.NET