在C#中的变量下获取函数的MethodInfo 附录

问题描述

我在C#中有一个特定的对象,将其称为MyCustomObjectMyCustomObject的类型为MyNamespace.CustomObject,每个该类型的对象都包含一个方法MyCustomMethod。我正在尝试获取MethodInfo的{​​{1}}(System.Reflection.MethodInfo),以便以后可以使用它来创建表达式树。但是,如果我仅使用MyCustomObject.MyCustomMethod,它将为类型typeof(MyCustomObject).GetMethod("MyMethodInfo")的所有对象返回一个通用方法。我怎么能只得到MyNamespace.CustomObject的{​​{1}}?

解决方法

在创建表达式树时(按this comment),您大概想使用Call工厂方法。

在您的情况下,您尝试创建一个表示实例方法调用,而不是静态方法调用的表达式树;它们之间的区别在于,实例方法调用使用实例,而静态方法调用不使用实例。

要创建这样的表达式树,您需要某种表示实例的表达式树。它可能是属性或字段,或者是另一个方法调用的结果。但是,如果要将其应用于现有实例,则可以将实例传递到Constant工厂方法中。

对于不带参数的实例方法调用,您可以将此节点传递到Call重载之一中,该重载代表实例方法调用,例如this one

类似这样的东西:

// using System.Linq.Expressions.Expression

CustomObject MyCustomObject = /* initialized somehow */
var methodInfo = typeof(CustomObject).GetMethod("MyCustomMethod");
var expr = Lambda(
    Call(
        Constant(MyCustomObject),methodInfo
    ),new ParameterExpression[] { }  // if the LambdaExpression has parameters,add them here
);

附录

使用编译器生成类似的表达式树时:

CustomObject MyCustomObject = /* initialized somehow */
Expression<Action> expr = () => MyCustomObject.MyCustomMethod();

MyCustomObject不是用ConstantExpression来代表,而是用MemberAccessExpression来代表。 C#编译器将封闭变量(在本例中为lambda表达式中的MyCustomObject)重写为对编译器生成的对象的属性访问。代替了对Constant的调用,代表MyCustomObject的相应工厂方法看起来像这样:

// using System.Linq.Expressions.Expression

PropertyOrField(
    Constant(<<closure_object>>),"MyCustomObject"
)

我们无法在代码中编写这样的内容,因为我们的代码无法访问<<closure_object>>实例。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...