【问题标题】:Expression Lambda error "Argument types do not match"表达式 Lambda 错误“参数类型不匹配”
【发布时间】:2014-04-22 15:37:00
【问题描述】:

对于我的一生,我无法弄清楚我做错了什么。我花了很多时间以这种方式和那种方式调整这段代码,但无法弄清楚我在这里的哪个参数中错了哪种类型。

请擅长构建 .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);
}

【问题讨论】:

  • 嘿,如何将其分解为更简单的表达式,直到它开始工作或出现本地化错误?
  • @Andrey 我尝试过以一种方式分解它,但对我来说,范围界定如何与这些东西一起工作并不是很清楚,所以如果我将它们分开,如何将变量从一个表达式传递到另一个表达式是对我来说不是很清楚。不过我会再试一次,不会受伤。
  • @Andrey 谢谢!我终于弄明白了,IfThenElse 的返回方式不像块,我必须在 ifthenelse 内部分配,然后立即获得值。
  • 是的,Expression.IfThenElse 是表达式,而不是常规 C# 中的语句。

标签: c# .net lambda expression


【解决方案1】:

我解决了这个问题!问题是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);
}

【讨论】:

  • 您可以使用Expression.Condition 来简化此操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-09
  • 2021-01-02
  • 2016-03-03
相关资源
最近更新 更多