【问题标题】:Is it possible to use an expression tree to define a method body for dynamic types?是否可以使用表达式树来定义动态类型的方法体?
【发布时间】:2013-06-11 14:10:14
【问题描述】:

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

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

【问题讨论】:

  • 顺便说一句,属性访问器的通用命名约定是get_X,而不是X_get。虽然这很可能无关紧要。
  • 确实如此,我会改变我的问题。

标签: c# reflection expression-trees


【解决方案1】:

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

【讨论】:

  • 是的,看来你是对的。虽然它似乎没有记录在案。
  • 我的 LINQ 表达式树的 Java 实现没有这个限制:)。
  • 如果你能用Java做LINQ,我想知道x 1000万。
  • LINQ 是一个超载的术语。我所做的是实现 LINQ/DLR 表达式树 API 和编译器(有一些增强)。我纯粹用它来生成运行时代码。它与 LINQ 的收集/查询相关方面无关。我只是更喜欢使用声明性表达式树而不是原始字节码:)。
  • 我明白了。 I just prefer working with declarative expression trees to raw bytecode - 绝对是这个。
【解决方案2】:

【讨论】:

    【解决方案3】:

    我正在使用的一个小技巧(仍然有问题)是创建 2 个具有相同签名的函数,1 个静态函数和 1 个获取实例的函数。表达式树使用 MethodBuilder 进行编译,然后您创建一个(几乎)相同的签名(使用新的 MethodBuilder),您可以为其发出调用静态“双胞胎”函数所需的 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' 之前您无法知道这一点),因此我们需要通过与 this.GetType().GetMethod(...) 等效的 IL 来获取它
    2. 将传递给函数的参数(包括“this”,即 LdArg_0)复制到对象数组中
    3. 直接调用“Invoke”函数

    我有点担心走这条路(因为复杂的公共 API)。但是,我真的需要类型正确声明(和工作)实例方法,而不仅仅是模仿实例行为。到目前为止,这似乎可以解决问题。

    【讨论】:

    • 我想补充一个很好的答案,您可以使用 OpCodes.Tailcall 来提高性能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    相关资源
    最近更新 更多