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