表达式 API 引发异常:从作用域 '' 引用的类型为“x”的变量“x”,但未定义

本文关键字:API 变量 未定义 表达式 引用 类型 异常 作用域 | 更新日期: 2023-09-27 18:20:45

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",但未定义。

如何解决此异常?

表达式 API 引发异常:从作用域 '' 引用的类型为“x”的变量“x”,但未定义

您不会像第一次那样将参数传递给第二次创建的 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);
}