Domanda

  

Possibile duplicato:
   Come posso trovare il metodo che ha chiamato la corrente metodo?

Ho un metodo in un oggetto che viene chiamato da un numero di posti all'interno dell'oggetto. C'è un modo semplice e veloce per ottenere il nome del metodo che ha chiamato questo metodo popolare.

ESEMPIO di codice pseudo:

public Main()
{
     PopularMethod();
}

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

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

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

All'interno di PopularMethod () vorrei vedere il valore di Main se è stato chiamato da Main ... Mi piacerebbe per vedere " ButtonClick " se PopularMethod () è stato chiamato da ButtonClick

Stavo guardando il System.Reflection.MethodBase.GetCurrentMethod () ma questo non mi procurerebbe il metodo di chiamata. Ho esaminato la classe StackTrace ma non mi è davvero piaciuto eseguire un'intera traccia dello stack ogni volta che viene chiamato quel metodo.

È stato utile?

Soluzione

Non credo che si possa fare senza tracciare lo stack. Tuttavia, è abbastanza semplice farlo:

StackTrace stackTrace = new StackTrace();
MethodBase methodBase = stackTrace.GetFrame(1).GetMethod();
Console.WriteLine(methodBase.Name); // e.g.

Tuttavia, penso che tu debba davvero fermarti e chiederti se è necessario.

Altri suggerimenti

In .NET 4.5 / C # 5, questo è semplice:

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

Il compilatore aggiunge automaticamente il nome del chiamante; così:

void Foo() {
    PopularMethod();
}

passerà in " Foo " .

Questo è davvero molto semplice.

public void PopularMethod()
{
    var currentMethod = System.Reflection.MethodInfo
        .GetCurrentMethod(); // as MethodBase
}

Ma attenzione, sono un po 'scettico sul fatto che il metodo sia efficace. Puoi farlo per assicurarti che il compilatore JIT non si frapponga.

[System.Runtime.CompilerServices.MethodImpl(
 System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public void PopularMethod()
{
    var currentMethod = System.Reflection.MethodInfo
        .GetCurrentMethod();
}

Per ottenere il metodo di chiamata:

[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();
}

Basta inserire un parametro

public void PopularMethod(object sender)
{

}

IMO: se è abbastanza buono per eventi, dovrebbe essere abbastanza buono per questo.

Mi sono spesso ritrovato a voler fare questo, ma ho sempre finito con il refactoring del design del mio sistema, quindi non capisco questo "quot wagging the dog " anti-modello. Il risultato è sempre stata un'architettura più solida.

Mentre puoi sicuramente rintracciare lo Stack e immaginarlo in questo modo, ti esorto a ripensare il tuo progetto. Se il tuo metodo ha bisogno di conoscere una sorta di "stato", direi semplicemente di creare un enum o qualcosa del genere, e prenderlo come parametro sul tuo PopularMethod (). Qualcosa del genere. Sulla base di ciò che stai postando, tracciare lo stack sarebbe eccessivo IMO.

Penso che sia necessario utilizzare la classe StackTrace e quindi StackFrame.GetMethod () nel frame successivo.

Però sembra una cosa strana usare Reflection . Se stai definendo PopularMethod , non puoi definire un parametro o qualcosa per passare le informazioni che desideri davvero. (Oppure inserisci una classe base o qualcosa del genere ...)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top