2012-11-20 25 views
3

這聽起來很明顯,但我遇到了很多困難。基本上,我正在做的是使用Reflection.Emit生成一個方法,然後我想調用它。到目前爲止,我已經構建了方法,但是在創建方法後我無法獲取對該方法的引用,因爲「在創建類型之前不支持調用的成員。」用Reflection.Emit創建一個方法,然後調用它

這是我基本上做到:

AssemblyBuilder assembly; 
ModuleBuilder module; 
TypeBuilder containerTypeBuilder; 
Type containerType; 
var name = new AssemblyName(); 
name.Name = "DynamicWrapper"; 
var domain = Thread.GetDomain(); 
assembly = domain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave); 
module = assembly.DefineDynamicModule(assembly.GetName().Name, false); 
containerTypeBuilder = module.DefineType("__DynamicWrapperType", 
           TypeAttributes.Public | TypeAttributes.Class | 
           TypeAttributes.AutoClass | 
           TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | 
           TypeAttributes.AutoLayout, typeof(object)); 
//build method 
var mb = containerTypeBuilder.DefineMethod("generatedmethod" + (unique++), 
           MethodAttributes.Public | MethodAttributes.Static, typeof (int), 
           new Type[] {}); 
//build method body and all that 
..... 
var type=module.GetType("__DynamicWrapperType"); 
var info=type.GetMethod(mb.Name, BindingFlags.Static | BindingFlags.Public); //error here 

我怎麼把我的新建造方法,並加載它,這樣我就可以調用它?

另外,我試過mb.Invoke,但是這樣會產生「調用的成員在動態模塊中不受支持」。

回答

4

如果要創建單獨的方法(一個或多個),然後DynamicMethod是一個更好的選擇(特別是因爲你的方法是靜態的) - 你只需要使用CreateDelegate(指定委託類型),到該委託,並調用。這也是較少的開銷,並收藏。

但是,如果你不得不使用MethodBuilder:你必須在TypeBuilder使用CreateType,那麼現在真正類型(從CreateType返回)使用反射。

+0

不知道爲什麼我從一開始就不考慮DynamicMethod。我會看看這是否會起作用(這只是單元測試,因此對於可收集來說不是非常重要,但聽起來更容易使用) – Earlz

+0

@Earlz它更容易**:沒有AssemblyBuilder,ModuleBuilder,AssemblyName,TypeBuilder ,MethodBuilder - 基本上只是ILGenerator。 –

+0

是的,剛剛轉換爲在大約2秒內使用DynamicMethod,並得到這一切都修復:)現在只是爲了找到是什麼讓我的IL拋出一個無效的程序異常 – Earlz

相關問題