首页 > 解决方案 > 将 C# 表达式树编译为方法时,是否可以访问“this”?

问题描述

我正在尝试动态生成一个实现给定接口的类。因此,我需要实现一些方法。我想避免直接发出 IL 指令,所以我尝试使用表达式树和 CompileToMethod。不幸的是,其中一些方法需要访问生成的类的一个字段(就像我将 this.field 写入我正在实现的方法中一样)。是否可以使用表达式树访问“this”?(“this”是指将调用该方法的对象。)

如果是的话,这样的方法在表达式树中会是什么样子?

int SomeMethod() {
    return this.field.SomeOtherMethod();
}

标签: c#code-generationexpression-trees

解决方案


Expression.Constant或者ParameterExpression是你的朋友;例子:

var obj = Expression.Constant(this);
var field = Expression.PropertyOrField(obj, "field");
var call = Expression.Call(field, field.Type.GetMethod("SomeOtherMethod"));
var lambda = Expression.Lambda<Func<int>>(call);

或者:

var obj = Expression.Parameter(typeof(SomeType));
var field = Expression.PropertyOrField(obj, "field");
var call = Expression.Call(field, field.Type.GetMethod("SomeOtherMethod"));
var lambda = Expression.Lambda<Func<SomeType, int>>(call, obj);

(在后一种情况下,您将this作为参数传入,但这意味着您可以存储 lambda 并将其重新用于不同的目标实例对象)

dynamic如果你的名字是固定的,这里的另一个选择可能是:

dynamic obj = someDuckTypedObject;
int i = obj.field.SomeOtherMethod();

推荐阅读