سؤال

For the life of me I cannot figure out what I'm getting wrong. I've spent a hell of a lot of time tweaking this code this way and that, and cannot figure out what type I'm getting wrong in what argument here.

Please can someone who's good at constructing .NET expressions manually look at this code and let me know what I'm getting wrong.

The purpose of this code block is to hopefully result in something like:

initialParameter =>
{
    var firstExpressionResult = firstExpressionToExecute(initialParameter);
    if (firstExpressionResult == nullValueExpression)
        return defaultExpressionResult;
    else
        return secondExpressionToExecute(firstExpressionResult);
}

Here is the code I've come up with, I've tried various forms of this trying to get it right but this seems to be the furthest forward I've so far managed:

public static Expression<Func<T, V>> AddClause<T, U, V>(this Expression<Func<T, U>> firstExpressionToExecute, Expression<Func<U, V>> secondExpressionToExecute)
{
    var initialParameter = Expression.Parameter(typeof(T), "initialParameter");
    var firstExpressionResult = Expression.Variable(typeof(U), "firstExpressionsResult");
    var nullValueExpression = Expression.Variable(typeof(U), "nullValueExpression");
    var successExpressionResult = Expression.Variable(typeof(V), "successExpressionResult");
    var defaultExpressionResult = Expression.Variable(typeof(V), "defaultExpressionResult");
    var returnTarget = Expression.Label(typeof(V));

    return Expression.Lambda<Func<T, V>>(
        Expression.Block(
            typeof(V),
            new ParameterExpression[] { firstExpressionResult, defaultExpressionResult, nullValueExpression },
            new Expression[] {
                Expression.Assign(firstExpressionResult, Expression.Invoke(firstExpressionToExecute, initialParameter)),
                Expression.IfThenElse(
                    Expression.Equal(firstExpressionResult, nullValueExpression),
                    defaultExpressionResult,
                    Expression.Invoke(secondExpressionToExecute, firstExpressionResult))
            }),
        initialParameter);
}
هل كانت مفيدة؟

المحلول

I resolved this! The problem was the IfThenElse expression neither does an implicit return like a Block does, nor does it allow an explicit return using an Expression.Return (at least not as far as I could tell, unless I was doing them wrong), the solution was to change the code so the IfThenElse assigned a return value, and at the end of the block I just put the return value for the implicit return.

Here's the fixed code:

public static Expression<Func<T, V>> AddClause<T, U, V>(this Expression<Func<T, U>> firstExpressionToExecute, Expression<Func<U, V>> secondExpressionToExecute)
{
    var initialParameter = Expression.Parameter(typeof(T), "initialParameter");
    var firstExpressionResult = Expression.Variable(typeof(U), "firstExpressionsResult");
    var nullValueExpression = Expression.Variable(typeof(U), "nullValueExpression");
    var returnValue = Expression.Variable(typeof(V), "returnValue");
    var defaultExpressionResult = Expression.Variable(typeof(V), "defaultExpressionResult");

    return Expression.Lambda<Func<T, V>>(
        Expression.Block(
            typeof(V),
            new ParameterExpression[] { firstExpressionResult, defaultExpressionResult, nullValueExpression, returnValue },
            new Expression[] {
                Expression.Assign(firstExpressionResult, Expression.Invoke(firstExpressionToExecute, initialParameter)),
                Expression.IfThenElse(
                    Expression.Equal(firstExpressionResult, nullValueExpression),
                    Expression.Assign(returnValue, defaultExpressionResult),
                    Expression.Assign(returnValue, Expression.Invoke(secondExpressionToExecute, firstExpressionResult))),
                returnValue
            }),
        initialParameter);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top