【问题标题】:Lambda compile failure, reference defined in '' scope, but is not definedLambda 编译失败,在 '' 范围内定义了引用,但未定义
【发布时间】:2013-01-22 19:10:27
【问题描述】:

在下面的简单sn-p中:

static void Main(string[] args)
{
    Expression<Func<string, bool>> equal = s => s == "test";
    LambdaExpression lambda = Expression.Lambda(equal.Body, Expression.Parameter(typeof(string), "s"));
    lambda.Compile();
}

编译方法失败并返回InvalidOperationException

"从范围''引用的'System.String'类型的变量's', 但它没有定义”。

虽然我发现了其他类似的问题,但我无法理解所提供的答案。

LambdaExpression 的 DebugView 包含以下内容:

.Lambda #Lambda1<System.Func`2[System.String,System.Boolean]>(System.String $s) {
    $s == "test"
}

所以我在这个问题的其他示例中看到,参数和用法不匹配,这在此处似乎不是问题。我做错了什么?

【问题讨论】:

  • DebugView 不会告诉您是否有两次使用相同的参数,或者两个不同的参数恰好具有相同的名称。
  • @spajce 这不是同一个问题。
  • 这是一个相关的问题先生 :)

标签: c# expression-trees


【解决方案1】:

lambda 表达式的参数不使用基于名称的相等性,它们使用引用相等性。因此,在您的表达式中,您有两个完全不同的参数,称为 s,一个已定义但未使用,另一个已使用但未定义。

所以,基本上,您的表达式类似于s1 =&gt; s2 == "test",这就是它无法编译的原因。最简单的解决方法是使用与原始表达式相同的参数:

LambdaExpression lambda = Expression.Lambda(equal.Body, equal.Parameters.Single());

如果您真的想使用自己的参数,则需要将 lambda 主体中原始参数的所有实例替换为新参数。可能最好的方法是使用ExpressionVisitor

【讨论】:

  • 谢谢,这完全解决了我的问题,并给出了清晰的解释。
  • 谢谢你,陌生人!在阅读您的帖子之前浪费了 5 个小时!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-07
  • 2023-03-28
  • 2015-10-28
  • 2016-10-15
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
相关资源
最近更新 更多