系統。反思。Emit.DynamicMethod 類別
本文提供此 API 參考文件的補充備註。
您可以使用 DynamicMethod 類別在運行時間產生和執行方法,而不需要產生動態元件和動態類型,即可包含方法。 當回收物件時 DynamicMethod ,會回收 Just-In-Time 編譯程式所建立的可執行程序代碼。 動態方法是產生和執行少量程序代碼的最有效率的方式。
動態方法可以匿名裝載,也可以以邏輯方式與模組或類型相關聯。
如果動態方法是以匿名方式裝載,則它位於系統提供的元件中,因此會與其他程式碼隔離。 根據預設,它無法存取任何非公用數據。 匿名裝載的動態方法如果已授ReflectionPermissionReflectionPermissionFlag.RestrictedMemberAccess與旗標,則可以限制略過 JIT 編譯程式的可見性檢查。 動態方法存取其非公用成員的元件信任層級,必須等於發出動態方法之呼叫堆疊的信任層級或子集。 如需匿名裝載動態方法的詳細資訊,請參閱 逐步解說:在部分信任案例中發出程序代碼。
如果動態方法與您指定的模組相關聯,動態方法就會有效地全域到該模組。 它可以存取模組中的所有類型,以及類型的所有
internal
(Friend
在 Visual Basic 中) 成員。 不論您是否已建立模組,都可以將動態方法與任何模組產生關聯,前提是呼叫堆疊可以滿足包含RestrictedMemberAccess程式代碼的旗標需求ReflectionPermission。 ReflectionPermissionFlag.MemberAccess如果旗標包含在授與中,動態方法可以略過 JIT 編譯程式的可見度檢查,並存取模組中宣告之所有類型或任何元件中任何其他模組的私用數據。注意
當您指定動態方法相關聯的模組時,該模組不得位於用於匿名裝載的系統提供元件中。
如果動態方法與您指定的類型相關聯,則不論存取層級為何,它都可以存取該類型的所有成員。 此外,可以略過 JIT 可見性檢查。 這可讓動態方法存取相同模組或任何元件中任何其他模組中所宣告之其他類型的私用數據。 您可以將動態方法與任何類型產生關聯,但您的程式代碼必須同時RestrictedMemberAccess授ReflectionPermission與 和 MemberAccess 旗標。
下表顯示匿名裝載的動態方法可存取哪些類型和成員,不論是否授與 JIT 可見度檢查,取決於 ReflectionPermission 是否授與 RestrictedMemberAccess 旗標。
可見度檢查 | 不使用 RestrictedMemberAccess |
使用 RestrictedMemberAccess |
---|---|---|
不略過 JIT 可見性檢查 | 任何元件中的公用類型公用成員。 | 任何元件中的公用類型公用成員。 |
略過 JIT 可見性檢查,但有限制 | 任何元件中的公用類型公用成員。 | 所有類型的成員,只有在信任層級等於或小於發出動態方法之元件的信任層級的元件中。 |
下表顯示動態方法可存取哪些類型和成員,而動態方法與模組或模組中的類型相關聯。
略過 JIT 可見性檢查 | 與模組相關聯 | 與類型建立關聯 |
---|---|---|
No | 模組中公用、內部和私用類型的公用和內部成員。 任何元件中的公用類型公用成員。 |
相關聯型別的所有成員。 模組中所有其他型別的公用和內部成員。 任何元件中的公用類型公用成員。 |
Yes | 任何元件中所有類型的所有成員。 | 任何元件中所有類型的所有成員。 |
與模組相關聯的動態方法具有該模組的許可權。 與類型相關聯的動態方法具有包含該類型的模組許可權。
動態方法及其參數不需要命名,但您可以指定名稱來協助偵錯。 動態方法或其參數不支援自定義屬性。
雖然動態方法是 static
方法(Shared
Visual Basic 中的方法),但委派系結的寬鬆規則可讓動態方法系結至物件,因此當使用該委派實例呼叫時,它會像實例方法一樣。 示範此方法 CreateDelegate(Type, Object) 多載的範例。
驗證
下列清單摘要說明動態方法可以包含無法驗證程式代碼的條件。 (例如,如果動態方法的 InitLocals 屬性設定為 false
,則無法驗證。
- 與安全性關鍵元件相關聯的動態方法也是安全性關鍵,而且可以略過驗證。 例如,沒有以傳統型應用程式執行之安全性屬性的元件會被視為運行時間的安全性關鍵。 如果您將動態方法與元件產生關聯,動態方法可以包含無法驗證的程序代碼。
- 如果包含無法驗證程式代碼的動態方法與具有層級 1 透明度的元件相關聯,則 Just-In-Time (JIT) 編譯程式會插入安全性需求。 只有在動態方法是由完全信任的程式代碼執行時,需求才會成功。 請參閱 安全性透明程式代碼層級 1。
- 如果包含無法驗證程式代碼的動態方法與具有層級 2 透明度的元件相關聯(例如mscorlib.dll),則會擲回例外狀況(由 JIT 編譯程式插入),而不是提出安全性需求。 請參閱 安全性透明程式代碼層級 2。
- 匿名裝載的動態方法,其中包含無法驗證的程序代碼一律會擲回例外狀況。 它永遠無法略過驗證,即使它是由完全信任的程式代碼所建立和執行。
針對無法驗證程式代碼擲回的例外狀況會因叫用動態方法的方式而有所不同。 如果您使用從 CreateDelegate 方法傳回的委派叫用動態方法, VerificationException 則會擲回 。 如果您使用 方法叫用 Invoke 動態方法, TargetInvocationException 則會以內部 VerificationException擲回 。