【问题标题】:Get MethodInfo of a function under a variable in C#获取C#变量下函数的MethodInfo
【发布时间】:2020-08-27 19:41:28
【问题描述】:

我在 C# 中有一个特定的对象,称之为MyCustomObjectMyCustomObject 属于 MyNamespace.CustomObject 类型,并且该类型的每个对象都包含一个方法 MyCustomMethod。我正在尝试获取MyCustomObject.MyCustomMethodMethodInfo (System.Reflection.MethodInfo),以便以后可以使用它来创建表达式树。但是,如果我只使用typeof(MyCustomObject).GetMethod("MyMethodInfo"),它会为MyNamespace.CustomObject 类型的所有对象返回一个通用方法。如何获得 MethodInfoMyCustomObject.MyCustomMethod

【问题讨论】:

  • 没有这样的东西。方法存在于类中,而不是类的实例中。你得到 MethodInfoInvoke 它传递你想要的实例
  • 这个问题对我来说没有多大意义。我怀疑 OP 只需要使用 myInstance.GetType() 而不是 typeof(MyCustomObject)
  • 我要做的是构造一个调用MyCustomObject.MyCustomMethod的表达式树,我去使用Expression.Call,但是我需要MethodInfo。如何构造一个表达式树来调用MyCustomObject.MyCustomMethod
  • @4yl1n 你做的正是你所做的。这就是您需要在该类型上调用该方法的方法信息。
  • 对于对象的特定实例,没有 MethodInfo 这样的东西。想一想在不使用反射的情况下你将如何/用 C# 编写什么样的代码,然后发布它来解释你正在尝试做什么。

标签: c# lambda expression expression-trees methodinfo


【解决方案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)重写为对编译器生成的对象的属性访问。代表MyCustomObject 的相应工厂方法不是调用Constant,而是如下所示:

// using System.Linq.Expressions.Expression

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

我们不能在代码中写这样的东西,因为我们的代码无权访问&lt;&lt;closure_object&gt;&gt; 实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    • 1970-01-01
    相关资源
    最近更新 更多