2010-06-03 12 views
30

ho una classe che apparire come il seguente:using System.Reflection per ottenere un metodo Nome completo

public class MyClass 
{ 

... 

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

... 

} 

Il valore di myName è "MyMethod".

Esiste un modo per utilizzare Reflection per ottenere un valore di "MyClass.MyMethod" per myName?

+1

Correzione: dovrebbe essere System.Reflection.MethodBase.GetCurrentMethod() Nome – aads

risposta

50

Si potrebbe guardare il ReflectedType del MethodBase si ottiene da GetCurrentMethod, vale a dire,

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

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

Esattamente quello che stavo cercando.. Grazie! –

+0

Basta notare che il 'ReflectedType' non tiene conto del polimorfismo di runtime come ci si poteva aspettare .. – user2864740

4

estensione Ruben, è possibile ottenere il nome completo come questo:

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

è possibile aggiungerlo a un metodo statico che riceve un parametro MethodBase e genera la stringa.

4

È possibile ottenere il nome completo come questo:

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

E per ottenere il nome del metodo completo con i parametri:

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 soluzione più utile.Includere FullName consente di individuare la classe quando il codice base ha ripetuto nomi di classi in spazi dei nomi diversi. E l'inclusione dei parametri aiuta a distinguere tra metodi sovraccaricati. –

2

Grazie per i posti di cui sopra, che mi ha aiutato a creare una forte digitare il sistema di binding per MVC 4 HTMLHelpers come segue.

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; 

    } 

Per utilizzare il codice di cui sopra, in ogni CSHTML Vista:

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

Questo mi permette di associare qualsiasi proprietà in una ViewModel a qualsiasi tipo di elemento HTML che voglio. Nell'esempio sopra riportato, lego il campo del nome per i dati selezionati postati dopo che l'utente ha effettuato la selezione. Il viewmodel dopo il postback mostra automaticamente il valore selezionato.

2

In C# 6 è possibile utilizzare nameof:

string myName = nameof(MyMethod); 
+1

Sì, ma restituisce solo il nome, non il nome completo. Nell'esempio fornito, restituisce la stringa '" MyMethod "', non '" MyClass.MyMethod "'. – Matt

5

Credo che in questi giorni, è meglio fare questo:

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

Ho cercato questo in modo che potessi registrare i nomi qualificati e questo è l'approccio che ho finito per adottare. Solo perché è piccolo, semplice e fa quello di cui ho bisogno. – onesixtyfourth

0

Avrai problemi durante l'esecuzione all'interno metodi asincrone. Ecco come risolvere che:

Se è necessario qualificare completamente il nome della classe, dovrete utilizzare DeclaringType.FullName invece di DeclaringType.Name

Questo codice non funziona bene per i metodi anonimi 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; 
    } 
} 

Ecco un esempio di utilizzo:

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