【发布时间】:2018-08-20 06:05:24
【问题描述】:
我想动态生成程序集,它可以具有不同结构的功能。更准确地说,这些函数可以是递归的,它们可以在同一个程序集中调用其他函数等。我发现System.Reflection 模块理论上提供了执行此操作的工具,但实际上我遇到了这种方法的许多缺点。例如 - 我无法通过 TypeBuilder 和 MethodBuilder 类生成递归函数,因为会抛出异常(使用不完整类型)。我了解到我可以通过IlGenerator 生成自递归函数 - 但它太麻烦了 - 我希望有一种更简单的方法来做到这一点。
这是我演示问题的程序(在生成方法Fact 时抛出以下异常:
Exception thrown: 'System.NotSupportedException' in mscorlib.dll Additional information: Specified method is not supported..
代码:
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Linq.Expressions;
namespace GenericFuncs
{
public class ProgramBuilder
{
public Type createMyProgram()
{
var assmName = new AssemblyName("DynamicAssemblyExample");
var assmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assmName, AssemblyBuilderAccess.RunAndSave);
var moduleBuilder = assmBuilder.DefineDynamicModule(assmName.Name, assmName.Name + ".dll");
var myProgramType = buildMyProgram(moduleBuilder, moduleBuilder.DefineType("MyProgram", TypeAttributes.Public));
assmBuilder.Save(assmName.Name + ".dll");
return myProgramType;
}
private Type buildMyProgram(ModuleBuilder mb, TypeBuilder programBuilder)
{
buildFactFunction2(mb, mb.GetType("MyProgram"), programBuilder.DefineMethod("InfLoop", MethodAttributes.Public | MethodAttributes.Static));
buildFactFunction(mb, mb.GetType("MyProgram"), programBuilder.DefineMethod("Fact", MethodAttributes.Public | MethodAttributes.Static));
return programBuilder.CreateType();
}
private void buildFactFunction(ModuleBuilder mb, Type program_type, MethodBuilder methodBuilder)
{
var param = Expression.Parameter(typeof(int), "n");
var lambda = Expression.Lambda(Expression.Call(methodBuilder, param), param);
lambda.CompileToMethod(methodBuilder);
}
static public void my_print(string s)
{
Console.WriteLine(s);
}
private void buildFactFunction2(ModuleBuilder mb, Type program_type, MethodBuilder methodBuilder)
{
var il = methodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldstr, "a");
il.Emit(OpCodes.Call, typeof(ProgramBuilder).GetMethod("my_print"));
il.Emit(OpCodes.Call, methodBuilder);
il.Emit(OpCodes.Ret);
}
}
class Program
{
static void Main(string[] args)
{
var pbuilder = new ProgramBuilder();
var ptype = pbuilder.createMyProgram();
Console.ReadLine();
}
}
}
感谢任何帮助。
【问题讨论】:
标签: c# reflection system.reflection