繁体   English   中英

C# - 是否可以从Action中获取方法的所有者类型?

[英]C# - Is it possible to get the owner type of a method from an Action?

我有一个用一些方法实现接口的类。 我也有一个Action参数的方法,我传递了Interface方法。 是否有可能获得具有该方法的所有者的类型?

编辑这是包装器:

private void Wrapper (params Action[] actions)
{
    var action = actions.FirstOrDefault();
    var type = action.Method.DeclaringType.Name;
}

private void test()
{
   Wrapper(()=> _GC.ChargeCancellation(""));
}

出于演示目的,我不会遍历该集合。

我想要_GC的类型。

编辑:我误读了这个例子,并认为它正在使用方法组转换。 您当然可以在委托中获取该方法:

public void Wrapper(Action action)
{
    MethodInfo method = action.Method;
    Type type = method.DeclaringType; // TestClass
    string name = method.Name; // Hello
}

如果你传递一个具有多个动作的委托实例,我不确定会使用哪种方法......但在这种情况下它应该不是问题。

Doh - 我误读了这个问题。 当你使用lambda表达式时,它将在调用类中构建一个额外的方法 - 是包含对_GC的引用的方法。

如果您不想要这种行为,您应该更改Wrapper以接受params Expression<Action>[] actions - 然后您可以适当地检查表达式树并找出这种方式的调用。 有时它有点繁琐,但它是可行的。 查看表达式树的Body ,它将表示方法调用。 请注意,如果您仍想执行操作,可以在表达式树上调用Compile以获取委托。

实际上,我应该首先发现这一点,但既然乔恩没有,我也不会感觉太糟糕:)

您在问题中必须开始的代码无法编译:

Wrapper(() => TestClass.Hello);

这不是完整的代码。 你要么必须:

Wrapper(TestClass.Hello);
        ^
        |
        +-- notice the missing () => here

要么:

Wrapper(() => TestClass.Hello());
                             ^
                             |
                             +-- notice the added parenthesis here

现在你已经编辑了你的问题,很明显你有第二个表格。

这两者之间存在细微差别。 对我们来说很微妙,但对编译器很重要:

Wrapper(TestClass.Hello);
        ^------+------^
               |
               +-- This is a method group

Wrapper(() => TestClass.Hello());
              ^------+--------^
                     |
                     +-- This is a method call

方法组是对方法(或其重载)的引用,方法调用是可执行代码。

编译器的不同之处在于,在第一段代码中,编译器会将方法组包装成一个动作,基本上就像这样编译它:

Wrapper(new Action(TestClass.Hello));

因此,您将该方法传递给Action委托中的Wrapper方法。

但是,第二种形式的处理完全不同。 编译器现在生成一个包含代码的新方法,然后将新方法传递给Wrapper方法而不是代码。

因此,您的代码实际上如下所示:

public static void Main()
{
    Wrapper(new Action(TempMethod1));
}

private static void TempMethod1()
{
    TestClass.Hello();
}

这就是为什么你看到表单类作为方法的所有者,因为它就是它的本质。

我在评论中询问你是否正在接受代表或表达的原因是我的大脑正以半速运转。 它检测到奇怪的东西,但不是整个画面。

如果你想将这样的代码传递给一个方法,并使用它,你有两个选择:

  1. 对于委托,使用反射,反编译代码并对其进行分析,找到方法调用并找出它所在的类
  2. 对于表达式,分析表达式的部分(这需要C#3或更高版本)

由于这两件事都不是微不足道的,我不打算在这里发布任何代码,只要说你要问的是一个新问题。 在这两个中,如果可以的话,我建议你选择表达方式。

暂无
暂无

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

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