共用方式為


OpCodes.Constrained 欄位

定義

限制進行虛擬方法呼叫的類型。

public: static initonly System::Reflection::Emit::OpCode Constrained;
public static readonly System.Reflection.Emit.OpCode Constrained;
 staticval mutable Constrained : System.Reflection.Emit.OpCode
Public Shared ReadOnly Constrained As OpCode 

欄位值

備註

下表列出指令的十六進位和Microsoft中繼語言 (MSIL) 元件格式,以及簡短的參考摘要:

格式 元件格式 描述
FE 16 <T> 約束。 thisType 在型別上呼叫虛擬方法,限制為類型 T

constrained 前置詞只能在 callvirt 指令上使用。

此時 MSIL 堆疊的狀態必須如下所示:

  1. managed 指標 ptr會推送至堆疊。 ptr 的類型必須是managed指標(&),才能 thisType。 請注意,這與未使用 callvirt 指令的情況不同,其預期參考 thisType

  2. 透過 argNarg1 的方法自變數會推送至堆疊,就像未使用 callvirt 指令一樣。

constrained 前置詞的設計目的是讓 callvirt 指令以統一的方式進行,而不論 thisType 是實值型別還是參考型別。

callvirtmethod 指令前面加上 constrainedthisType時,會執行指令,如下所示:

  • 如果 thisType 是參考型別(與實值型別相反),則會取值 ptr 並傳遞為 methodcallvirt 的 『this』 指標。

  • 如果 thisType 為實值型別,且 thisType 實作 method,則會將 ptr 傳遞為 callmethod 指令的 'this' 指標,以 thisType實作 method

  • 如果 thisType 是實值型別,且 thisType 未實作 methodptr 會取值、boxed,並傳遞為 callvirtmethod 指令的 'this' 指標。

只有在 ObjectValueTypeEnum 上定義 method,且未由 thisType覆寫時,才會發生這個最後一個案例。 在此情況下,Boxing 會建立原始對象的複本。 不過,由於沒有 ObjectValueTypeEnum 修改對象狀態的方法,所以無法偵測到這個事實。

constrained 前置詞支援建立泛型程序代碼的 IL 產生器。 一般而言,callvirt 指令在實值型別上無效。 相反地,根據 ptr 的類型和所呼叫的方法,IL 編譯程式必須有效地執行上述的 『this』 轉換。 不過,當 ptr 是編譯時期未知的泛型型別時,就無法在編譯時期進行此轉換。

constrained opcode 可讓 IL 編譯程式以統一的方式呼叫虛擬函式,而不論 ptr 是實值型別還是參考型別。 雖然它適用於 thisType 是泛型型別變數的情況,但 constrained 前置詞也適用於非泛型型別,並可減少以語言產生虛擬呼叫的複雜性,以隱藏實值類型和參考型別之間的差異。

使用 constrained 前置詞也避免了實值型別的潛在版本設定問題。 如果未使用 constrained 前置詞,則必須根據實值類型是否覆寫 System.Object 的方法,發出不同的 IL。 例如,如果實值類型 V 覆寫 Object.ToString() 方法,就會發出 callV.ToString() 指令;如果沒有,則會發出 box 指令和 callvirtObject.ToString() 指令。 如果稍後移除覆寫,則會在前一個案例中發生版本控制問題,而稍後新增覆寫時,則會發生版本控制問題。

constrained 前置詞也可用於在實值型別上叫用介面方法,因為實作介面方法的實值型別方法可以使用 MethodImpl來變更。 如果未使用 constrained 前置詞,編譯程式會強制選擇要在編譯時期系結至的值型別方法。 使用 constrained 前置詞可讓 MSIL 系結至在運行時間實作介面方法的方法,而不是在編譯時期。

下列 Emit 方法多載可以使用 constrained opcode:

適用於