Jud*_*ngo 4 c# lambda expression-trees
当涉及到表达树时,我是新手,所以我不确定如何提出这个问题或使用什么术语.这是我正在尝试做的过于简化的版本:
Bar bar = new Bar();
Zap(() => bar.Foo);
public static void Zap<T>(Expression<Func<T>> source)
{
// HELP HERE:
// I want to get the bar instance and call bar.Zim() or some other method.
}
Run Code Online (Sandbox Code Playgroud)
如何在Zap方法中使用bar?
由于传递给Zap方法的表达式是树,因此您只需使用表达式树访问者遍历树并查找ConstantExpression表达式中的第一个树.它可能按以下顺序排列:
(((source.Body as MemberExpression).Expression as MemberExpression).Expression as ConstantExpression).Value
Run Code Online (Sandbox Code Playgroud)
请注意,bar实例由闭包捕获,闭包实现为内部类,实例作为成员,这是第二个MemberExpression的来源.
编辑
然后你必须从生成的闭包中获取字段,如下所示:
static void Main(string[] args)
{
var bar = new Bar();
bar.Foo = "Hello, Zap";
Zap(() => bar.Foo);
}
private class Bar
{
public String Foo { get; set; }
}
public static void Zap<T>(Expression<Func<T>> source)
{
var param = (((source.Body as MemberExpression).Expression as MemberExpression).Expression as ConstantExpression).Value;
var type = param.GetType();
// Note that the C# compiler creates the field of the closure class
// with the name of local variable that was captured in Main()
var field = type.GetField("bar");
var bar = field.GetValue(param) as Bar;
Debug.Assert(bar != null);
Console.WriteLine(bar.Foo);
}
Run Code Online (Sandbox Code Playgroud)
如果你知道"bar"的类型,你可以这样做(我在这里重复使用codekaizen答案中的一些内容):
static void Main(string[] args)
{
var bar = new Bar();
bar.Foo = "Hello, Zap";
Zap(() => bar.Foo);
Console.ReadLine();
}
private class Bar
{
public String Foo { get; set; }
}
public static void Zap<T>(Expression<Func<T>> source)
{
var body = source.Body as MemberExpression;
Bar test = Expression.Lambda<Func<Bar>>(body.Expression).Compile()();
Console.WriteLine(test.Foo);
}
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,您可以在表达式树中找到表示对象的表达式,然后编译并执行此表达式并获取对象(但顺便说一下,这不是一个非常快速的操作).所以,你缺少的是Compile()方法.您可以在这里找到更多信息:如何:执行表达式树.
在这段代码中,我假设你总是传递一个像"()=> object.Member"这样的表达式.对于真实场景,您需要分析您是否拥有所需的表达式(例如,如果它不是MemberExpression则抛出异常).或者使用ExpressionVisitor,这有点棘手.
我最近在这里回答了一个非常类似的问题: 如何在表达式树中订阅对象的事件?