簡體   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