variable '' of type '' referenced from scope '', but it is not defined

前端 未结 3 1379
生来不讨喜
生来不讨喜 2020-12-01 17:42

Well, the following code is self-explaining; I want to combine two expressions into one using And operator. The last line causes rune-time the error:

3条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-01 18:31

    As indicated in the other answer, you have two expressions where both have a parameter named y. Those don't automatically relate to each other.

    To properly compile your expression, you need to specify both source expression's parameters:

    Expression> e1 = (y => y.Length > 0);
    Expression> e2 = (y => y.Length < 5);
    
    var e3 = Expression.And(e1.Body, e2.Body);
    
    // (string, string) by adding both expressions' parameters.
    var e4 = Expression.Lambda>(e3, new[] 
    { 
        e1.Parameters[0], 
        e2.Parameters[0] 
    });
    
    Func compiledExpression = e4.Compile();
    
    bool result = compiledExpression("Foo", "Foo");
    

    Of course, you'd want an expression that combines both expressions with only one parameter. You can rebuild the expressions like this:

    ParameterExpression param = Expression.Parameter(typeof(string), "y");
    var lengthPropertyExpression = Expression.Property(param, "Length");
    
    var e1 = Expression.GreaterThan(lengthPropertyExpression, Expression.Constant(0));
    var e2 = Expression.LessThan(lengthPropertyExpression, Expression.Constant(5));
    
    var e3 = Expression.AndAlso(e1, e2);
    
    var e4 = Expression.Lambda>(e3, new[] { param });
    
    Func compiledExpression = e4.Compile();
    
    bool result = compiledExpression("Foo");
    

    As for your comment that you don't want to rebuild the expression, but do it on an existing expression's body and parameters: this works using ExpressionRewriter from Combining two lambda expressions in c# and AndAlso from Replacing the parameter name in the Body of an Expression:

    Expression> e1 = (y => y.Length > 0);
    Expression> e2 = (z => z.Length < 10);
    
    var e3 = ParameterReplacer.AndAlso(e1, e2);
    
    Func compiledExpression = e3.Compile();
    
    bool result = compiledExpression("Foo");
    

提交回复
热议问题