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

本文关键字:类型 方法 动态 定义 可以使 表达式 是否 | 更新日期: 2023-09-27 18:17:57

如果我要创建一个像这样的动态类型:

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更容易使用。

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

是,不是。LambdaExpression.CompileToMethod()方法将允许您将表达式树编译为MethodBuilder ,只有当方法是静态的。它不能用于实现实例方法,我相信这是您在示例中想要的。

这正是LambdaExpression.CompileToMethod()方法的作用。

我使用的一个小技巧(仍然有bug)是创建两个具有相同签名的函数,一个是静态的,一个是实例。使用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上发出:

  1. 一些调用来检索静态函数的MethodInfo(你不能知道,直到'CreateType'被调用),所以我们需要通过IL等效this. gettype ().GetMethod(…)
  2. 将传入函数的参数(包括'this',它是LdArg_0)复制到对象数组
  3. 直接调用Invoke函数

我有点担心走这条路(因为复杂的公共API)。但是,我确实需要类型具有正确声明(和工作)的实例方法,而不仅仅是模仿实例行为。