2014-07-10 4 views
3

이 개념의 다음과 같은 증거를 살펴 보시기 바랍니다 단락 회로 평가 개념을 무시 : 첫 번째 피연산자가 거짓으로 평가하기 때문에, 결과를식 트리 라이브러리는

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# 컴파일러는 올바르게 처리하지만 표현식 라이브러리는 올바르게 처리하지 않습니다.

단락 회로 평가를 위해 코드를 수정하는 방법은 무엇입니까?

+0

많은 두통을 피할 수 있으며 람다를 사용하여 수행 한 것처럼 람다를 사용하여 대신 표현을 만들 수 있습니다. 더 빠르고 쉬우 며 정확한 표현이 생성됩니다. – Servy

답변

7

Expression.And은 단락 회로가없는 AND 연산자 (&)를 나타냅니다.

Expression.AndAlso은 단락 회로 AND 연산자 (&&)를 나타냅니다.