2012-06-30 32 views
5

me he dado cuenta de que .NET 4.5 tiene un nuevo atributo llamado [CallerMemberNameAttribute] que, cuando se une a un parámetro de un método, suministrará el nombre de la cadena del método que llama ese método (si tiene sentido).C# obtienen llamadas Método de Seguimiento de la pila Sin

Sin embargo, desafortunadamente (porque quiero hacer algo con XNA), solo estoy apuntando a .NET 4.0.

Quiero ser capaz de hacer algo como:

void MethodA() { 
    MethodB(); 
} 

void MethodB() { 
    string callingMethodName = (...?); 
    Console.WriteLine(callingMethodName); 
} 

Donde mi salida sería MethodA.

sé que podría hacerlo a través de seguimiento de la pila, pero eso es a) No es fiable y b) de muy lenta ... Así que me pregunto si hay alguna otra manera de recoger esa información, sin embargo, que puede haber ...

Estaba esperando cualquier idea o conocimiento que alguien pueda tener sobre el tema. Gracias de antemano :)

+3

¿Pasa el nombre del método de llamada como una cadena? – Oded

+2

@Oded Bien, sí, claramente podría llamar a MethodB ("MethodA"), pero el punto es que estoy tratando de hacerlo de forma dinámica, de modo que si cambio MethodA a MethodC, no tengo que editar esa llamada también. – Xenoprimate

+0

No pudo mencionar ese punto en la pregunta. – Oded

Respuesta

13

Si usa Visual Studio 2012 para compilar esto, puede escribir su propio CallerMemberNameAttribute y usarlo de la misma manera que lo haría con .NET 4.5, incluso si todavía tiene como destino .NET 4.0 o 3.5. El compilador seguirá realizando la sustitución en el momento de la compilación, incluso apuntando a una versión de marco anterior.

Simplemente añadiendo hará el truco lo siguiente para su proyecto:

namespace System.Runtime.CompilerServices 
{ 
    public sealed class CallerMemberNameAttribute : Attribute { } 
} 
+0

Solo soy un programador aficionado, lo siento si esta es una pregunta estúpida, pero ¿hay alguna manera de que pueda ver la fuente del atributo CallerMemberNameAttribute de Microsoft? Para copiarlo, quiero decir. – Xenoprimate

+2

En general, sí, puede descompilar bibliotecas .NET utilizando ILSpy. http://wiki.sharpdevelop.net/ILSpy.ashx Sin embargo, los atributos rara vez producen algo interesante, ya que el bit interesante es más a menudo en cómo es usado por otro código. P.ej. de lo que dice @ReedCopsey, la transformación se realiza en tiempo de compilación por el compilador, no por el atributo en sí, y ni siquiera necesita el tiempo de ejecución de .NET 4.5, por lo que es probable que no vea ningún código interesante. –

+0

Ah, ¿entonces el compilador simplemente ve el nombre 'CallerMemberNameAttribute' e inserta su propia lógica?Si es así, ¿puedo simplemente crear un atributo en blanco con ese nombre y funcionará? – Xenoprimate

0

Usted puede proporcionar el nombre de la persona que llama como un parámetro para el método llamado. No es exactamente lo que estás pidiendo, pero funciona sin necesidad de acceder al marco de pila:

[MethodImpl(MethodImplOptions.NoInlining)] 
void MethodA() 
{ 
    string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name; 
    MethodB(methodName); 
} 

void MethodB(string callingMethodName) 
{ 
    Console.WriteLine(callingMethodName); 
} 

Mediante el uso de MethodBase.GetCurrentMethod(), puede asegurarse de que su aplicación sigue siendo refactor-seguro - si el nombre de sus cambios de método, los resultados seguirían siendo correctos

No olvide marcar su método de llamada con MethodImplOptions.NoInlining para evitar el método de alineación.

Cuestiones relacionadas