表达式树-如何获得声明实例? [英] Expression tree - how to get at declaring instance?

查看:72
本文介绍了表达式树-如何获得声明实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于表达式树,我是一个新手,所以我不确定如何问这个问题或使用什么术语.这是我正在尝试做的一个过于简化的版本:

I'm a newbie when it comes to expression trees, so I'm not sure how to ask this question or what terminology to use. Here's an overly-simplifed version of what I'm trying to do:

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.
}

如何进入Zap方法的内部?

How can I get to bar inside the Zap method?

推荐答案

由于传递给Zap方法的表达式是一棵树,因此只需要使用

Since the expression passed into your Zap method is a tree, you just need to walk the tree using an Expression Tree Visitor and look for the first ConstantExpression in the expression. It will likely be in the following sequence:

(((source.Body as MemberExpression).Expression as MemberExpression).Expression as ConstantExpression).Value

请注意,bar实例是由闭包捕获的,闭包是作为实例的内部类实现的,该实例作为成员,这是第二个MemberExpression的来源.

Note that the bar instance is captured by a closure, which is implemented as an internal class with the instance as a member, which is where the 2nd MemberExpression comes from.

编辑

然后,您必须像这样从生成的闭包中获取字段:

Then you have to get the field from the generated closure like so:

    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);
    }

这篇关于表达式树-如何获得声明实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆