Hello World
Spiga

统计一个表达式树拥有的节点数量

2009-10-31 21:05 by 老赵, 16219 visits

如果要统计表达式树的节点数量,我们可以编写一个Expression Visitor来完成这个任务:

public class ExpressionNodeCounter : ExpressionVisitor
{
    public int Calculate(Expression expr)
    {
        this.m_count = 0;
        this.Visit(expr);
        return this.m_count;
    }

    private int m_count;

    protected override Expression Visit(Expression exp)
    {
        this.m_count++;

        return base.Visit(exp);
    }
}

我们将表达式树传递给Visit方法后,Visit方法会将参数分派给其它方法,而其它方法又会将子节点交还给Visit方法进行递归调用,因此我们可以得知其实这个表达式树的每个节点都会“经过”Visit方法处理。因此,我们只需要重载Visit方法,查看它调用了几次就行了。值得注意的是,由于ExpressionVisitor只负责“遍历”,因此在进行“统计”、“收集信息”等任务的时候,都需要在子类内部保存临时信息。因此,许多ExpressionVisitor的实现其实都不是线程安全的。这点在使用或设计的时候都值得注意,我在开发FastLambda项目时,也对这个问题疏忽了。因此,虽然我用了一些方式来保证了FastEvaluator的线程安全,但事实上在相当长的时间内其实它都有着严重的问题。

那么,我们现在便可以用ExpressionNodeCounter来统计上次使用不同方式生成URL时所用到的Lambda表达式:

var blog = new Blog();
var post = new Post();

Expression<Action<HomeController>> expr = c => c.Post(blog, post);
Console.WriteLine(new ExpressionNodeCounter().Calculate(expr));

猜猜看结果如何?答案是7个节点,您是否能将它们一一指出?

其实,一般说来,由于自动生成闭包等机制,一个Lambda表达式实际构造出的节点总比我们“看出”的要多一些。

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

9 条回复

  1. Ivony...
    *.*.*.*
    链接

    Ivony... 2009-10-31 21:21:00

    我想说的是,虽然抢到了沙发。

    但这篇文章的确太短了。。。。

    所以看完了发现还没有回复。。。。

  2. Leon Weng
    *.*.*.*
    链接

    Leon Weng 2009-10-31 22:00:00

    为什么又是可望不可及的asp.net mvc

  3. Leon Weng
    *.*.*.*
    链接

    Leon Weng 2009-10-31 22:02:00

    恩?我怎么会是0楼 明明是2楼嘛

  4. Ivony...
    *.*.*.*
    链接

    Ivony... 2009-10-31 22:13:00

    Leon Weng:为什么又是可望不可及的asp.net mvc




    这个与ASP.NET MVC有关系吗?

  5. 亚历山大同志
    *.*.*.*
    链接

    亚历山大同志 2009-10-31 23:02:00

    唉,我又没有跟上潮流

  6. 老赵
    admin
    链接

    老赵 2009-10-31 23:19:00

    @Ivony...
    Leon Weng一定是看到其中某个关键字就放弃了,可惜可惜,呵呵。

  7. 老赵
    admin
    链接

    老赵 2009-10-31 23:20:00

    @亚历山大同志
    为什么说这是潮流啊……

  8. 老赵
    admin
    链接

    老赵 2009-10-31 23:20:00

    @Ivony...
    为下一片文章做准备,呵呵。

  9. 小城故事
    *.*.*.*
    链接

    小城故事 2009-10-31 23:55:00

    飘过最新鲜的文章,听了一下午老赵的MVC讲座苍凉的声音后

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我