【问题标题】:Expression tree library ignores short-circuit evaluation concept表达式树库忽略了短路评估概念
【发布时间】:2014-07-10 20:16:45
【问题描述】:

请看以下概念证明:

private class Model
{
    public string Data { get; set; }
    public bool NonEmpty() { return Data.Length > 0; }
}

private static Func<Model, bool> Compile()
{
    var type = typeof(Model);
    var expr = Expression.Parameter(typeof(Model));

    var subarg1 = Expression.Property(expr, type.GetProperty("Data"));
    var subarg2 = Expression.Constant(null);
    var arg1 = Expression.NotEqual(subarg1, subarg2);

    var arg2 = Expression.Call(expr, type.GetMethod("NonEmpty"));

    var tree = Expression.And(arg1, arg2); // Data != null && NonEmpty()
    var func = Expression.Lambda<Func<Model, bool>>(tree, expr).Compile();
    return func;
}

var model = new Model {Data = null};
var standardTest = model.Data != null && model.NonEmpty(); // returns false
var exprTreeTest = Compile().Invoke(model); // throws null ref exception

因为第一个操作数的计算结果为假,所以无论第二个操作数的值是什么,AND 运算的结果都是假的。这就是为什么不应该计算第二个操作数的原因。虽然 C# 编译器可以正确执行此操作,但表达式库却没有。

如何修复我的代码以遵守短路评估?

【问题讨论】:

  • 您可以为自己省去很多麻烦,并使用 lambda 来创建这样的表达式,而不是像以前那样做所有事情。它更快、更容易,并且会生成正确的表达式。

标签: c# .net expression-trees


【解决方案1】:

Expression.And 表示非短路 AND 运算符 (&amp;)。

Expression.AndAlso 表示短路 AND 运算符 (&amp;&amp;)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 2017-01-16
    • 1970-01-01
    • 2018-09-26
    相关资源
    最近更新 更多