OpCodes.Readonly 欄位

定義

指定後續陣列位址作業在執行階段不執行任何類型檢查,且會傳回限制其變動性的 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 方法。 對後續作業的影響是兩個:

  1. 在運行時間,不會執行類型檢查作業。 請注意,在參考型別陣列上使用 時,通常會有 ldelemastelem 指示的隱含型別檢查。 絕對不會有值類別的運行時間類型檢查,因此 readonly 在該案例中不會執行任何作業。

  2. 驗證程式會將位址作業的結果視為具有限制可變性的 Managed 指標。

指標稱為具有受限制的可變性,因為定義型別可控制值是否可以變動。 對於公開沒有就地更新值的公用字段或方法的值類別,指標是唯讀 (因此前置詞的名稱) 。 特別是,代表基本型別的類別 (例如 System.Int32) 不會公開 Mutator,因此是唯讀的。

以這種方式限制的 Managed 指標只能以下列方式使用:

  • 做為 objectldfldldfldastfldcallconstrained callvirt 指令的參數。

  • pointerldobj做為指令的參數或其中一個ldind指令。

  • source做為指令的參數cpobj

不允許所有其他作業,包括 stobjinitobjmkrefany 作業,或任何 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:

適用於