2011-06-27 34 views
7

我尝试使用以下策略来产生IL为递归方法, 首先我使用定义的类型下面的代码段生成IL为递归方法

private void InitializeAssembly(string outputFileName) 
     { 
      AppDomain appDomain = AppDomain.CurrentDomain; 
      AssemblyName assemblyName = new AssemblyName(outputFileName); 
      assemblyBuilder = appDomain.DefineDynamicAssembly(assemblyName, 
                   AssemblyBuilderAccess.Save); 
      moduleBuilder = assemblyBuilder.DefineDynamicModule(outputFileName, outputFileName + ".exe"); 
      typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public); 
      methodBuilder = typeBuilder.DefineMethod("Main", 
            MethodAttributes.Static | MethodAttributes.Public, 
            typeof(void), 
            System.Type.EmptyTypes); 
      ilGen = methodBuilder.GetILGenerator(); 

     } 

接着我开始如下面给出的,以产生IL为递归方法。

对于调用方法本身我用以下构建体中的方法主体内,

ilOfMethod.Emit(OpCodes.Call, typeBuilder.GetMethod("MethodName", new System.Type[] {typeof(arg1),typeof(arg2),etc})); 

最后使用以下方法装配保存生成的。

private void SaveAssembly(string outputFileName) 
     { 
      ilGen.Emit(OpCodes.Ret); 
      typeBuilder.CreateType(); 
      moduleBuilder.CreateGlobalFunctions(); 
      assemblyBuilder.SetEntryPoint(methodBuilder); 
      assemblyBuilder.Save(outputFileName + ".exe"); 
     } 

不幸的是,这是不工作,因为递归方法调用结构,在该方法内部返回null。此处问题是方法内部的递归调用(即ilOfMethod.Emit(OpCodes.Call, typeBuilder.GetMethod("MethodName", new System.Type[] {typeof(arg1),typeof(arg2),etc})); )返回null。由于我们实际上在SaveAssembly()方法内创建类型,因此这是可以接受的。所以我的问题是:是否有可能使用上述构造为递归方法生成IL?如果这是不可能的,请让我知道为递归方法生成IL的替代结构。

回答

7

我没有测试它,但如果我没有记错的话,你应该能够简单地使用的DefineMethod结果发出的指令Call

MethodBuilder method = typeBuilder.DefineMethod("MethodName", ...); 
... 

ILGenerator ilOfMethod = method.GetILGenerator(); 

... 
ilOfMethod.Emit(OpCodes.Call, method); 
+0

刚想发布相同。 ['MethodBuilder'](http://msdn.microsoft.com/zh-cn/library/system.reflection.emit.methodbuilder.aspx)从'MethodInfo'继承,所以在那里似乎有效。 –

+0

+1非常感谢!你的建议有效,我能够为递归方法生成IL –