Pobieranie nazwy metody wywołującej z wewnątrz metody [duplikat]

to pytanie ma już odpowiedzi tutaj : Jak mogę znaleźć metodę, która wywołała bieżącą metodę? (19 odpowiedzi) Zamknięte 3 miesiące temu.

Mam metodę w obiekcie, która jest wywoływana z wielu miejsc wewnątrz obiektu. Czy istnieje szybki i łatwy sposób, aby uzyskać nazwę metody, która nazywa tę popularną metodę.

Przykład Pseudo kodu:

public Main()
{
     PopularMethod();
}

public ButtonClick(object sender, EventArgs e)
{
     PopularMethod();
}

public Button2Click(object sender, EventArgs e)
{
     PopularMethod();
}

public void PopularMethod()
{
     //Get calling method name
}

Wewnątrz PopularMethod() chciałbym zobaczyć wartość Main Jeśli została wywołana z Main... Chciałbym zobaczyć "ButtonClick" Jeśli PopularMethod() został wywołany z ButtonClick

Patrzyłem na System.Reflection.MethodBase.GetCurrentMethod() ale to nie dostanę metody wywołania. Patrzyłem na klasę StackTrace, ale naprawdę nie podobało mi się uruchamianie całego śledzenia stosu za każdym razem, gdy ta metoda jest wywoływana.

Author: Cody Gray, 2009-03-05

7 answers

Nie sądzę, żeby można było to zrobić bez śledzenia stosu. Jednak jest to dość proste:

StackTrace stackTrace = new StackTrace();
MethodBase methodBase = stackTrace.GetFrame(1).GetMethod();
Console.WriteLine(methodBase.Name); // e.g.
Myślę jednak, że naprawdę musisz przestać i zadać sobie pytanie, czy to konieczne.
 72
Author: jason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 18:29:32

W. NET 4.5 / C # 5 jest to proste:

public void PopularMethod([CallerMemberName] string caller = null)
{
     // look at caller
}

Kompilator automatycznie dodaje nazwę wywołującego; tak więc:

void Foo() {
    PopularMethod();
}

Przejdzie "Foo".

 173
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-02 13:08:21

To naprawdę proste.

public void PopularMethod()
{
    var currentMethod = System.Reflection.MethodInfo
        .GetCurrentMethod(); // as MethodBase
}
[3]}ale bądź ostrożny, jestem trochę sceptyczny, czy inlining metoda ma jakiś efekt. Możesz to zrobić, aby upewnić się, że kompilator JIT nie będzie przeszkadzał.
[System.Runtime.CompilerServices.MethodImpl(
 System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public void PopularMethod()
{
    var currentMethod = System.Reflection.MethodInfo
        .GetCurrentMethod();
}

Aby uzyskać metodę wywołującą:

[System.Runtime.CompilerServices.MethodImpl(
 System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public void PopularMethod()
{
    // 1 == skip frames, false = no file info
    var callingMethod = new System.Diagnostics.StackTrace(1, false)
         .GetFrame(0).GetMethod();
}
 16
Author: John Leidegren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 18:34:53

Wystarczy podać parametr

public void PopularMethod(object sender)
{

}

IMO: jeśli jest wystarczająco dobry na wydarzenia, powinien być wystarczająco dobry na to.

 5
Author: Sruly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-27 02:46:16

Często znajdowałem siebie chcącego to zrobić, ale zawsze kończyłem refaktoryzację projektu mojego systemu, więc nie rozumiem tego" machania ogonem psa " anty-wzór. Rezultatem zawsze była solidniejsza Architektura.

 4
Author: JonPen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-07 08:01:59

Chociaż możesz na pewno prześledzić stos i rozgryźć go w ten sposób, zachęcam cię do przemyślenia swojego projektu. Jeśli twoja metoda musi wiedzieć o jakimś "stanie", powiedziałbym po prostu utwórz enum lub coś takiego i weź to jako parametr do PopularMethod (). Coś w tym stylu. Na podstawie tego, co publikujesz, śledzenie stosu byłoby IMO przesadą.

 1
Author: BFree,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 18:34:28

Myślę, że musisz użyć klasy StackTrace, a następnie StackFrame.GetMethod() na następnej klatce.

To wydaje się być dziwną rzeczą do używania Reflection. Jeśli definiujesz PopularMethod, nie możesz zdefiniować parametru lub czegoś, aby przekazać informacje, które naprawdę chcesz. (Albo umieścić w klasie podstawowej lub coś...)

 0
Author: C. Dragon 76,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-16 11:23:25