【问题标题】:Expression API throws exception: variable 'x' of type 'x' referenced from scope '', but it is not defined表达式 API 抛出异常:从范围 '' 引用的类型为 'x' 的变量 'x',但未定义
【发布时间】:2014-09-05 19:08:33
【问题描述】:
public class Program
{
    private static void Main()
    {
        ContrivedComparer.Compare<Person>(person => person.Name == "Calvin");
    }
}

public class Person
{
    public string Name { get; set; }
}

public class ContrivedComparer
{
    // this likely looks highly ill-advised out of context but this is contrived.
    public static readonly object comparatePerson = new Person { Name = "Ted" };

    public static void Compare<TComparate>(Expression<Func<TComparate, bool>> predicate) 
    {
        if (predicate.Compile()((TComparate)comparatePerson)) return;

        var expression = (BinaryExpression)predicate.Body;

        var actual = Expression.Lambda(expression.Left).Compile().DynamicInvoke();
        var expected = Expression.Lambda(expression.Right).Compile().DynamicInvoke();
    }
}

我希望actual 与左操作数具有相同的值,而expected 与右操作数具有相同的值。

但是,此代码会引发 InvalidOperationException 并带有以下消息:

从范围“”中引用了“Person”类型的变量“person”,但未定义。

如何解决此异常?

【问题讨论】:

  • actualexpected 最终应该是什么?
  • @Jon 对不起,如果我不清楚 Jon。我更新了我的问题。

标签: c# .net lambda expression expression-trees


【解决方案1】:

您没有像第一次那样将参数传递给您第二次创建的 lambda。需要在构造lambda时指明有参数,调用时传入值。

public static void Compare<TComparate>(Expression<Func<TComparate, bool>> predicate)
{
    if (predicate.Compile()((TComparate)comparatePerson)) return;

    var expression = (BinaryExpression)predicate.Body;

    var actual = Expression.Lambda(expression.Left, predicate.Parameters)
        .Compile().DynamicInvoke(comparatePerson);
    var expected = Expression.Lambda(expression.Right, predicate.Parameters)
        .Compile().DynamicInvoke(comparatePerson);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多