在不使用IL的情况下,将现有的C#方法附加到动态创建的Type中 [英] Attach existing C# method in dynamically created Type, without using IL

查看:68
本文介绍了在不使用IL的情况下,将现有的C#方法附加到动态创建的Type中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管此问题与此问题相似,但如何在运行时将方法附加到动态创建的C#类型上?,它不包含我要查找的答案。



我正在动态创建一个类型,然后将其保存在一个动态程序集DLL中,该DLL可在另一个项目中使用。



但是,我想将C#静态方法附加到此动态类型并在构造函数中调用它。 (因为此方法有点复杂)。



可以做到的一种方法是在另一个项目中用C#编写该方法,然后在动态类型中使用反射来调用它。但是,这将意味着动态类型必须随第二个程序集一起提供。



另一种方法是动态创建方法,然后为此编写IL。我想避免这种情况,因为我认为这会花费太多精力。有没有办法采用C#编写的现有方法,然后将其复制为动态类型?



更新



我当前正在使用AssemblyBuilder和ModuleBuilder.DefineType创建新类型。



我已经尝试使用MethodInfo.GetMethodBody()。GetILAsByteArray()来获取方法主体,然后使用MethodBuilder.CreateMethodBody()设置新定义的方法主体,但是由于某种原因无法正常工作。我注意到IL代码只有〜450个字节,这对我来说似乎太小了,因为其中有几个字符串文字很容易用完这个空间。我想我还需要做一些额外的事情才能使这项工作完成。



作为附带的问题,是否可以将整个类型复制到动态程序集中?

解决方案

有点晚了,但我使用表达式树解决了这个问题,并将其编译为在此处回答,以回应此SO问题。总结:



使用表达式树,而不必发出原始IL。

  var queue = new Queue< Expression>(); 
var arguments = Expression.Parameter(typeof(string []), args);

queue.Enqueue(Expression.Call(typeof(Console).GetMethod( WriteLine,new Type [] {}))));

var块= Expression.Block(queue);
var lambda = Expression.Lambda< Func< string [],int>>(block,new ParameterExpression [] {arguments});

lambda.CompileToMethod(builderMethod);
// builderMethod是先前创建的MethodBuilder实例。

这确实非常强大,并且绝对适合使用ILGenerator不需要微穿孔的情况。 / p>

Although this question is similar to this question, How do I attach a method to a dynamically-created C# type at runtime?, it does not contain the answer I am looknig for.

I am creating a type dynamically, and then saving this in a dynamic assembly DLL, which can be used in another project.

However, I want to "attach" a C# static method to this dynamic type and call it in the constructor. (since this method is a little complicated).

One way this can be done is to write the method in C# in another project, then use reflection in the dynamic type to invoke it. However, this would mean that the dynamic type will have to ship with a second assembly.

Another way would be to create the method dynamically and then write the IL for this. I would like to avoid this, since I think it would take too much effort. Is there a way to take an existing method written in C# and just "copy" it to the dynamic type?

Update

I am currently creating the new type using AssemblyBuilder, and ModuleBuilder.DefineType.

I have already tried grabbing the method body using MethodInfo.GetMethodBody().GetILAsByteArray() and then setting the newly defined method body using MethodBuilder.CreateMethodBody(), but does not work for some reason. I noticed that the IL code is only ~450 bytes, which seems too small for me, because there are several string literals in there that would easily use up this space. I am guessing there is some additional things I need to do to make this work.

As a side question, is it possible to copy an entire type into my dynamic assembly?

解决方案

A little late but I solved this using Expression Trees and compiling them into the MethodBuilder as answered here in response to this SO question. In summary:

Using Expression Trees instead of having to emit raw 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.

This is very powerful indeed and definitely suited for situations where micro-perf is not required using ILGenerator.

这篇关于在不使用IL的情况下,将现有的C#方法附加到动态创建的Type中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆