2010-06-03 27 views
30

tengo una clase que se parecen a lo siguiente:using System.Reflection obtener un método Nombre completo

public class MyClass 
{ 

... 

    protected void MyMethod() 
    { 
    ... 
    string myName = System.Reflection.MethodBase.GetCurrentMethod.Name; 
    ... 
    } 

... 

} 

El valor de myName es "MiMetodo".

¿Hay alguna manera de que pueda usar Reflection para obtener un valor de "MyClass.MyMethod" para myName en su lugar?

+1

Corrección: se debería System.Reflection.MethodBase.GetCurrentMethod() Nombre – aads

Respuesta

50

Se podría buscar en el ReflectedType del MethodBase que se obtiene de GetCurrentMethod, es decir,

MethodBase method = System.Reflection.MethodBase.GetCurrentMethod(); 
string methodName = method.Name; 
string className = method.ReflectedType.Name; 

string fullMethodName = className + "." + methodName; 
+0

Exactamente lo que estaba buscando.. ¡Gracias! –

+0

Solo tenga en cuenta que el 'ReflectedType' no cuenta para el polimorfismo de tiempo de ejecución como uno podría haber esperado .. – user2864740

4

La extensión de Ruben, se puede obtener el nombre completo de esta manera:

var info = System.Reflection.MethodBase.GetCurrentMethod(); 
var result = string.Format(
       "{0}.{1}.{2}()", 
       info.ReflectedType.Namespace, 
       info.ReflectedType.Name, 
       info.Name); 

puedes añadir a un método estático que recibe un parámetro MethodBase y genera la cadena.

4

Usted puede obtener el nombre completo de esta manera:

var fullMethodName = System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.FullName; 
14

Y para obtener el nombre del método a parámetros:

var method = System.Reflection.MethodBase.GetCurrentMethod(); 
var fullName = string.Format("{0}.{1}({2})", method.ReflectedType.FullName, method.Name, string.Join(",", method.GetParameters().Select(o => string.Format("{0} {1}", o.ParameterType, o.Name)).ToArray())); 
+0

+1 Definitivamente la solución más útil.La inclusión de FullName ayuda a identificar la clase cuando su base de código tiene nombres de clase repetidos en diferentes espacios de nombres. E incluir los parámetros ayuda a distinguir entre métodos sobrecargados. –

2

Gracias por los puestos de arriba, que me ayudó a crear una fuerte escriba el sistema de enlace para MVC 4 HTMLHelpers de la siguiente manera.

public static MvcHtmlString StrongTypeBinder(this HtmlHelper htmlhelper, Expression<Func<object, string>> SomeLambda) 
    { 
     var body = SomeLambda.Body; 
     var propertyName = ((PropertyInfo)((MemberExpression)body).Member).Name; 
     HtmlString = @" 
      <input type='text' name='@Id' id='@Id'/> 
      "; 
     HtmlString = HtmlString.Replace("@Id", propertyName); 
     var finalstring = new MvcHtmlString(HtmlString); 
     return finalstring; 

    } 

Para usar el código anterior en cualquier vista CSHTML:

@Html.StrongTypeBinder(p=>Model.SelectedDate) 

Esto me permite enlazar cualquier propiedad en un modelo de vista a cualquier tipo de elemento HTML que quiero. En el ejemplo anterior, estoy vinculando el campo de nombre para los datos seleccionados publicados después de que el usuario realiza la selección. El modelo de vista después de la publicación posterior muestra automáticamente el valor seleccionado.

2

En C# 6, se pueden utilizar nameof:

string myName = nameof(MyMethod); 
+1

Sí, pero eso devuelve solo el nombre, no el nombre completo. En el ejemplo dado, devuelve la cadena '" MyMethod "', no '" MyClass.MyMethod "'. – Matt

5

Creo que en estos días, lo mejor es hacer esto:

string fullMethodName = $"{typeof(MyClass).FullName}.{nameof(MyMethod)}"; 
+1

He estado buscando esto para poder registrar nombres calificados y este es el enfoque que terminé adoptando. Solo porque es pequeño, simple y hace lo que necesito. – onesixtyfourth

0

Vas a tener problemas cuando se ejecuta dentro de los métodos asincrónicos. He aquí cómo arreglar eso:

Si tiene que calificar totalmente el nombre de la clase, que tendrá que utilizar en lugar de DeclaringType.FullNameDeclaringType.Name

Este código no funciona muy bien para los métodos anónimos o lambda.

static string GetMethodContextName() { 
    var name = new StackTrace().GetFrame(1).GetMethod().GetMethodContextName(); 
} 

static string GetMethodContextName(this MethodBase method) { 
    if (method.DeclaringType.GetInterfaces().Any(i => i == typeof(IAsyncStateMachine))) { 
     var generatedType = method.DeclaringType; 
     var originalType = generatedType.DeclaringType; 
     var foundMethod = originalType.GetMethods(Instance | Static | Public | NonPublic | DeclaredOnly) 
      .Single(m => m.GetCustomAttribute<AsyncStateMachineAttribute>()?.StateMachineType == generatedType); 
     return foundMethod.DeclaringType.Name + "." + foundMethod.Name; 
    } else { 
     return method.DeclaringType.Name + "." + method.Name; 
    } 
} 

He aquí un ejemplo de uso:

class Program { 
    static void Main(string[] args) { 
     // outputs Program.Main 
     Console.WriteLine(GetMethodContextName()); 
    } 
} 
Cuestiones relacionadas