问题描述
我在C#中有一个特定的对象,将其称为MyCustomObject
。 MyCustomObject
的类型为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>>
实例。