是否可以使用表达式树来定义动态类型的方法体?

时间:2013-06-11 14:10:14

标签: c# reflection expression-trees

如果我正在创建这样的动态类型:

TypeBuilder dynaType = dynaModule.DefineType(typeof(T).Name + "_ORMProxy");

dynaType.AddInterfaceImplementation(typeof(IServiceTable));

// (1) Implement: (String) IServiceTable.TableName { get; }
FieldBuilder tableNameField = dynaType.DefineField("tableName", typeof(String), FieldAttributes.Private);
MethodBuilder tableNamePublicGetAccessor = dynaType.DefineMethod("get_tableName", MethodAttributes.Public);
tableNamePublicGetAccessor...

是否可以将GetAccessor方法设置为表达式树。他们比直接IL更容易使用。

3 个答案:

答案 0 :(得分:4)

是和否。仅当方法为静态时,LambdaExpression.CompileToMethod()方法才允许您将表达式树编译为MethodBuilder 。它不能用于实现实例方法,我相信这是你想要的例子。

答案 1 :(得分:3)

答案 2 :(得分:2)

我正在使用的一个小技巧(仍然是错误的)是创建具有相同签名的2个函数,1个静态和1个实例。使用MethodBuilder编译表达式树,然后创建一个(几乎)相同的签名(使用新的MethodBuilder),您可以为其发出调用静态“twin”函数所需的IL。

一个例子就是这样(在C#中):

//You create a static function (from ExpressionTree) matching signature:
static void MyInstanceFunction(object, string, string, string);

//Then create an instance (HasThis) function matching:
void MyInstanceFunction(string, string, string);

然后在实例MethodBuilder上使用Reflection.Emit发送:

  1. 一些调用来检索静态函数的MethodInfo(在调用'CreateType'之前你不能知道这一点)所以我们需要通过IL的等价物来获取它.GetType()。GetMethod(...)
  2. 将传递给函数的参数(包括'this',即LdArg_0)复制到对象数组
  3. 直接调用“调用”功能
  4. 我对这条路线感到有些担心(因为公共API错综复杂)。但是,我真的需要类型来正确声明(和工作)实例方法,而不仅仅是模仿实例行为。到目前为止,这似乎已经成功了。