Pregunta

  

Posible duplicado:
   ¿Cómo puedo encontrar el método que llamó al actual método?

Tengo un método en un objeto que se llama desde varios lugares dentro del objeto. ¿Existe una manera rápida y fácil de obtener el nombre del método que llamó a este método popular?

Pseudocódigo EJEMPLO:

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 de PopularMethod () me gustaría ver el valor de Main si se llamó desde Main ... Me gustaría para ver " ButtonClick " si PopularMethod () fue llamado desde ButtonClick

Estaba mirando el System.Reflection.MethodBase.GetCurrentMethod () pero eso no me dará el método de llamada. Observé la clase StackTrace pero realmente no me gustó ejecutar un seguimiento completo de la pila cada vez que se llama a ese método.

¿Fue útil?

Solución

No creo que se pueda hacer sin rastrear la pila. Sin embargo, es bastante simple hacer eso:

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

Sin embargo, creo que realmente debes detenerte y preguntarte si esto es necesario.

Otros consejos

En .NET 4.5 / C # 5, esto es simple:

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

El compilador agrega el nombre de la persona que llama automáticamente; entonces:

void Foo() {
    PopularMethod();
}

pasará en " Foo " .

Esto es realmente muy simple.

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

Pero ten cuidado, soy un poco escéptico respecto a si la incorporación del método tiene algún efecto. Puede hacer esto para asegurarse de que el compilador JIT no se interponga en el camino.

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

Para obtener el método de llamada:

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

Solo pasa un parámetro

public void PopularMethod(object sender)
{

}

OMI: si es lo suficientemente bueno para eventos, debería ser lo suficientemente bueno para esto.

A menudo me he encontrado con ganas de hacer esto, pero siempre termino refactorizando el diseño de mi sistema para no tener esto "Cola moviendo al perro". anti-patrón. El resultado siempre ha sido una arquitectura más robusta.

Si bien puedes rastrear la pila y resolverlo de esa manera, te recomiendo que repenses tu diseño. Si su método necesita saber acerca de algún tipo de "estado", diría que simplemente cree una enumeración o algo así, y tome eso como un Parámetro a su Método Popular (). Algo en ese sentido. En función de lo que está publicando, el seguimiento de la pila sería una exageración de la OMI.

Creo que necesitas usar la clase StackTrace y luego StackFrame.GetMethod () en el siguiente marco.

Esto parece algo extraño de usar Reflexión para, sin embargo. Si está definiendo PopularMethod , no puede definir un parámetro o algo para pasar la información que realmente desea. (O poner en una clase base o algo así ...)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top