虽然这个问题类似于How do I attach a method to a dynamically-created C# type at runtime?这个问题,但它不包含我想要的答案。
我正在动态创建一个类型,然后将其保存在动态程序集DLL中,该DLL可以在另一个项目中使用。
但是,我想将C#静态方法“附加”到此动态类型并在构造函数中调用它。 (因为这种方法有点复杂)。
可以这样做的一种方法是在另一个项目中用C#编写方法,然后在动态类型中使用反射来调用它。但是,这意味着动态类型必须附带第二个程序集。
另一种方法是动态创建方法,然后为此编写IL。我想避免这种情况,因为我认为这需要付出太多努力。有没有办法采用用C#编写的现有方法,只是将其“复制”到动态类型?
更新
我目前正在使用AssemblyBuilder和ModuleBuilder.DefineType创建新类型。
我已经尝试使用MethodInfo.GetMethodBody()获取方法体.GetILAsByteArray()然后使用MethodBuilder.CreateMethodBody()设置新定义的方法体,但由于某种原因不起作用。我注意到IL代码只有~450字节,这对我来说似乎太小了,因为那里有几个字符串文字很容易用掉这个空间。我猜我还需要做一些额外的事情来完成这项工作。
作为一个附带问题,是否可以将整个类型复制到我的动态装配中?
答案 0 :(得分:1)
有点晚了,但是我使用表达式树解决了这个问题,并将它们编译为方法构建器answered here以响应this SO question。总结:
使用表达式树而不必发出原始IL。
var queue = new Queue<Expression>();
var arguments = Expression.Parameter(typeof(string []), "args");
queue.Enqueue(Expression.Call(typeof(Console).GetMethod("WriteLine", new Type [] { })));
var block = Expression.Block(queue);
var lambda = Expression.Lambda<Func<string [], int>>(block, new ParameterExpression [] { arguments });
lambda.CompileToMethod(builderMethod);
// builderMethod is a MethodBuilder instance created earlier.
这非常强大,非常适合使用ILGenerator不需要micro-perf的情况。