Recuperar o nome do método chamado de dentro de um método [duplicado]
-
03-07-2019 - |
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.
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 ...)