OpCodes.Constrained 欄位
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
限制進行虛擬方法呼叫的類型。
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 堆疊的狀態必須如下所示:
managed 指標
ptr
會推送至堆疊。ptr
的類型必須是managed指標(&
),才能thisType
。 請注意,這與未使用callvirt
指令的情況不同,其預期參考thisType
。透過
argN
arg1
的方法自變數會推送至堆疊,就像未使用callvirt
指令一樣。
constrained
前置詞的設計目的是讓 callvirt
指令以統一的方式進行,而不論 thisType
是實值型別還是參考型別。
當 callvirt
method
指令前面加上 constrained
thisType
時,會執行指令,如下所示:
如果
thisType
是參考型別(與實值型別相反),則會取值ptr
並傳遞為method
之callvirt
的 『this』 指標。如果
thisType
為實值型別,且thisType
實作method
,則會將ptr
傳遞為call
method
指令的 'this' 指標,以thisType
實作method
。如果
thisType
是實值型別,且thisType
未實作method
則ptr
會取值、boxed,並傳遞為callvirt
method
指令的 'this' 指標。
只有在 Object、ValueType或 Enum 上定義 method
,且未由 thisType
覆寫時,才會發生這個最後一個案例。 在此情況下,Boxing 會建立原始對象的複本。 不過,由於沒有 Object、ValueType和 Enum 修改對象狀態的方法,所以無法偵測到這個事實。
constrained
前置詞支援建立泛型程序代碼的 IL 產生器。 一般而言,callvirt
指令在實值型別上無效。 相反地,根據 ptr
的類型和所呼叫的方法,IL 編譯程式必須有效地執行上述的 『this』 轉換。 不過,當 ptr
是編譯時期未知的泛型型別時,就無法在編譯時期進行此轉換。
constrained
opcode 可讓 IL 編譯程式以統一的方式呼叫虛擬函式,而不論 ptr
是實值型別還是參考型別。 雖然它適用於 thisType
是泛型型別變數的情況,但 constrained
前置詞也適用於非泛型型別,並可減少以語言產生虛擬呼叫的複雜性,以隱藏實值類型和參考型別之間的差異。
使用 constrained
前置詞也避免了實值型別的潛在版本設定問題。 如果未使用 constrained
前置詞,則必須根據實值類型是否覆寫 System.Object 的方法,發出不同的 IL。 例如,如果實值類型 V
覆寫 Object.ToString() 方法,就會發出 call
V.ToString()
指令;如果沒有,則會發出 box
指令和 callvirt
Object.ToString()
指令。 如果稍後移除覆寫,則會在前一個案例中發生版本控制問題,而稍後新增覆寫時,則會發生版本控制問題。
constrained
前置詞也可用於在實值型別上叫用介面方法,因為實作介面方法的實值型別方法可以使用 MethodImpl
來變更。 如果未使用 constrained
前置詞,編譯程式會強制選擇要在編譯時期系結至的值型別方法。 使用 constrained
前置詞可讓 MSIL 系結至在運行時間實作介面方法的方法,而不是在編譯時期。
下列 Emit 方法多載可以使用 constrained
opcode: