OpCodes.Readonly 欄位
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
指定後續陣列位址作業在執行階段不執行任何類型檢查,且會傳回限制其變動性的 Managed 指標。
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
欄位值
備註
下表列出指令的十六進位和 Microsoft 中繼語言 (MSIL) 元件格式,以及簡短的參考摘要:
格式 | 元件格式 | Description |
---|---|---|
FE 1E | readonly。 | 指定後續的數位位址作業在運行時間不會執行類型檢查,而且它會傳回受限制可變性的 Managed 指標。 |
此前置詞只能緊接在指令前面 ldelema
,並呼叫陣列上的特殊 Address
方法。 對後續作業的影響是兩個:
在運行時間,不會執行類型檢查作業。 請注意,在參考型別陣列上使用 時,通常會有
ldelema
和stelem
指示的隱含型別檢查。 絕對不會有值類別的運行時間類型檢查,因此readonly
在該案例中不會執行任何作業。驗證程式會將位址作業的結果視為具有限制可變性的 Managed 指標。
指標稱為具有受限制的可變性,因為定義型別可控制值是否可以變動。 對於公開沒有就地更新值的公用字段或方法的值類別,指標是唯讀 (因此前置詞的名稱) 。 特別是,代表基本型別的類別 (例如 System.Int32) 不會公開 Mutator,因此是唯讀的。
以這種方式限制的 Managed 指標只能以下列方式使用:
做為
object
ldfld
、ldflda
、stfld
、call
或constrained callvirt
指令的參數。pointer
ldobj
做為指令的參數或其中一個ldind
指令。source
做為指令的參數cpobj
。
不允許所有其他作業,包括 stobj
、 initobj
或 mkrefany
作業,或任何 stind
指示。
前置詞的目的是 readonly
在泛型程式代碼中從數位列擷取專案時避免類型檢查。 例如,表達式 arr[i].m()
,其中陣列 arr
的專案類型是一種泛型型別,其限制為具有 方法 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
指令。
一般而言,略過運行時間檢查是否保存參考型別的陣列元素會不安全。 若要安全,請務必確保不會透過這個指標修改陣列。 驗證程式規則可確保這一點。 受限制的Managed指標可以當做實例方法呼叫的對象傳遞,因此它不是針對實值型別嚴格來說只讀的,但實值型別沒有類型安全性問題。
下列 Emit 方法多載可以使用 readonly
opcode: