表达式树库忽略了短路评估概念

时间:2014-07-10 20:16:45

标签: c# .net expression-trees

请看下面的概念证明:

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

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

如何修复我的代码以尊重短路评估?

1 个答案:

答案 0 :(得分:8)

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

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

相关问题