c# - 表达式树库忽略短路求值概念

标签 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 运算的结果都是 false。这就是为什么不应该计算第二个操作数的原因。虽然 C# 编译器可以正确地做到这一点,但表达式库却不能。

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

最佳答案

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

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

关于c# - 表达式树库忽略短路求值概念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24685496/

相关文章:

c# - DictionarySectionHandler 和 NameValueSectionHandler 之间有区别吗?

.net - 如何从 "non-standard"事件中获取 Rx 中的 IObservable<T>?

c# - 使用参数名称动态创建委托(delegate)

c# - 有没有办法创建一个委托(delegate)来获取和设置 FieldInfo 的值?

c# - 使用文本框值在 HTML 中构建 URL

c# - 异常抛出

c# - 实现自定义通用列表/队列/堆栈组合的有效方法

c# - Entity Framework 6 + MySQL : Model tables are not created automatically

c# - 在 Visual Studio 中快速注释/* 选定的 C# 代码 */(不是//整行)

使用 Expression.Call 的 C# 构造 lambda 不喜欢某些类型作为参数?