繁体   English   中英

表达式树中的错误:System.InvalidOperationException:从范围''引用的类型'A'的变量'消息',但未定义

[英]Error in expression tree: System.InvalidOperationException: variable 'message' of type 'A' referenced from scope '', but it is not defined

我需要构建Action来表示以下代码: (new P()).Handle(argument type of A)

我对此有一个表达:

Expression.Lambda<Action<A>>(Expression.Call(Expression.New(typeof(P)),
typeof(P).GetMethod("Handle", 
  BindingFlags.Instance | BindingFlags.Public), 
  Expression.Parameter(typeof(A), 
  "message")), 
Expression.Parameter(typeof(A), "message"))
.Compile();

但是当我尝试编译它时会抛出错误。 错误是:

System.TypeInitializationException:“ PerformanceBenchma rk.Test”的类型初始值设定项引发了异常。 ---> System.InvalidOperationException:从范围''引用的类型为'PerformanceBenchmark.A'的变量'message',但未定义

我的代码如下所示:

public class A
{
}

public interface IInt<T>
{
    void Handle(T item);
}

public class P : IInt<A>
{
    public void Handle(A item)
    {
        return;
    }
}

public class Test
{
    public static readonly Action<A> _expr = Expression.Lambda<Action<A>>(Expression.Call(Expression.New(typeof(P)), typeof(P).GetMethod("Handle", BindingFlags.Instance | BindingFlags.Public), Expression.Parameter(typeof(A), "message")), Expression.Parameter(typeof(A), "message")).Compile(); 
}

我的目标是测量_expr(new A())调用的速度。 但是现在在表达式编译上失败了。

问题是您要两次调用Expression.Parameter ,所以您有两个不同的参数表达式。 不幸的是,它们没有名称绑定。

因此,解决方案就是简单地使用多个语句, 一次创建一个ParameterExpression ,然后再使用两次。 这样的代码也更容易阅读:

var method = typeof(P).GetMethod("Handle", BindingFlags.Instance | BindingFlags.Public);
var parameter = Expression.Parameter(typeof(A), "message");
var ctorCall = Expression.New(typeof(P));
var methodCall = Expression.Call(ctorCall, method, parameter);
var expressionTree = Expression.Lambda<Action<A>>(methodCall, parameter);
var compiled = expressionTree.Compile();

当然,要使用该代码初始化静态字段,您将需要将其放入辅助方法或静态构造函数中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM