官網原文地址:https://ourpalm.github.io/ILRuntime/public/v1/guide/delegate.html
ILRuntime中使用委託
如果只在熱更新的DLL項目中使用的委託,是不需要任何額外操作的,就跟在通常的C#裏那樣使用即可
如果你需要將委託實例傳給ILRuntime外部使用,那則根據情況,你需要額外添加適配器或者轉換器。
需要注意的是,一些編譯器功能也會生成將委託傳出給外部使用的代碼,例如:
Linq當中where xxxx == xxx,會需要將xxx == xxx這個作爲lambda表達式傳給Linq.Where這個外部方法使用
OrderBy()方法,原因同上
如果在運行時發現缺少註冊某個指定類型的委託適配器或者轉換器時,ILRuntime會拋出相應的異常,根據提示添加註冊即可。
委託適配器(DelegateAdapter)
如果將委託實例傳出給ILRuntime外部使用,那就意味着需要將委託實例轉換成真正的CLR(C#運行時)委託實例,這個過程需要動態創建CLR的委託實例。由於IL2CPP之類的AOT編譯技術無法在運行時生成新的類型,所以在創建委託實例的時候ILRuntime選擇了顯式註冊的方式,以保證問題不被隱藏到上線後才發現。
同一個參數組合的委託,只需要註冊一次即可,例如:
delegate void SomeDelegate(int a, float b); Action<int, float> act; |
這兩個委託都只需要註冊一個適配器即可。 註冊方法如下
appDomain.DelegateManager.RegisterMethodDelegate<int, float>(); |
如果是帶返回類型的委託,例如:
delegate bool SomeFunction(int a, float b); Func<int, float, bool> act; |
需要按照以下方式註冊
appDomain.DelegateManager.RegisterFunctionDelegate<int, float, bool>(); |
委託轉換器(DelegateConvertor)
ILRuntime內部是使用Action,以及Func這兩個系統自帶委託類型來生成的委託實例,所以如果你需要將一個不是Action或者Func類型
的委託實例傳到ILRuntime外部使用的話,除了委託適配器,還需要額外寫一個轉換器,將Action和Func轉換成你真正需要的那個委託類型。
比如上面例子中的SomeFunction類型的委託,其所需的Convertor應如下實現:
app.DelegateManager.RegisterDelegateConvertor<SomeFunction>((action) => { return new SomeFunction((a, b) => { return ((Func<int, float, bool>)action)(a, b); }); }); |
建議
爲了避免不必要的麻煩,以及後期熱更出現問題,建議項目遵循以下幾點:
-
儘量
避免不必要的
跨域委託調用 -
儘量使用
Action以及Func
這兩個系統內置萬用委託類型