Pergunta

Duplicate possíveis:
Como posso encontrar o método que chamou o atual método?

Eu tenho um método em um objeto que é chamado a partir de um número de lugares dentro do objeto. Existe uma maneira rápida e fácil de obter o nome do método que chama este método popular.

Pseudo Código Exemplo:

public Main()
{
     PopularMethod();
}

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

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

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

Dentro PopularMethod() eu gostaria de ver o valor de Main se ele foi chamado de Main ... Eu gostaria de ver "ButtonClick" se PopularMethod() foi chamado de ButtonClick

Eu estava olhando para o System.Reflection.MethodBase.GetCurrentMethod() mas isso não vai me o método de chamada. Eu olhei para a classe StackTrace mas eu realmente não gostava executando todo um rastreamento de pilha de cada vez que o método é chamado.

Foi útil?

Solução

Eu não acho que isso pode ser feito sem rastreamento da pilha. No entanto, é bastante simples de fazer isso:

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

No entanto, eu acho que você realmente tem que parar e perguntar-se se tal for necessário.

Outras dicas

Em .NET 4.5 / C # 5, este é simples:

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

O compilador acrescenta o nome da pessoa automaticamente; assim:

void Foo() {
    PopularMethod();
}

passará em "Foo".

Este é realmente muito simples.

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

Mas ser através de cuidado, eu sou um pouco cético para se inlining o método tem qualquer efeito. Você pode fazer isso para se certificar de que o compilador JIT não vai ficar no caminho.

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

Para obter o método de chamada:

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

Apenas passar um parâmetro

public void PopularMethod(object sender)
{

}

IMO:. Se é bom o suficiente para eventos ele deve ser bom o suficiente para este

Eu sempre achei a minha auto querer fazer isso, mas sempre terminando refatoração o design do meu sistema para que eu não entendo isso "cauda abanando o cachorro" anti-padrão. O resultado tem sido sempre uma arquitetura mais robusta.

Enquanto você pode mais definitley rastrear a pilha e figura-lo dessa maneira, gostaria de exortá-lo a repensar o seu design. Se o seu método precisa de saber sobre algum tipo de "estado", eu diria que apenas criar um enum ou algo assim, e tomar isso como um parâmetro para o seu PopularMethod (). Algo ao longo dessas linhas. Baseado no que você está postando, traçando a pilha seria um exagero IMO.

Eu acho que você precisa fazer para usar a classe StackTrace e depois StackFrame.GetMethod() sobre o próximo quadro.

Esta parece ser uma coisa estranha de usar Reflection pois embora. Se você estiver definindo PopularMethod, não pode ir definir um parâmetro ou algo para passar a informação que você realmente quer. (Ou colocar em uma classe base ou algo assim ...)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top