表达式Lambda错误“参数类型不匹配”

时间:2014-04-22 15:37:01

标签: c# .net lambda expression

对于我的生活,我无法弄清楚我的错误。我花了很多时间用这种方式来调整这段代码,并且无法弄清楚我在这个论点中出错的类型。

擅长构建.NET表达式的人可以手动查看此代码,让我知道我的错误。

此代码块的目的是希望产生类似的结果:

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

以下是我提出的代码,我尝试了各种形式的尝试,但这似乎是我迄今为止最远的管理方式:

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);
}

1 个答案:

答案 0 :(得分:2)

我解决了这个问题!问题是IfThenElse表达式既不像Block那样进行隐式返回,也不允许使用Expression.Return进行显式返回(至少不是我所知道的,除非我做错了),解决方案是更改代码,以便IfThenElse分配一个返回值,并在块的末尾我只是为隐式返回设置返回值。

这里是固定代码:

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);
}