web-dev-qa-db-fra.com

Utilisation de System.Reflection pour obtenir le nom complet d'une méthode

J'ai un cours qui ressemble à ceci:

public class MyClass
{

...

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

...

}

La valeur de myName est "MyMethod". 

Est-il possible d'utiliser Reflection pour obtenir une valeur de "MyClass.MyMethod" pour myName à la place?

36
Onion-Knight

Vous pouvez regarder la ReflectedType de la MethodBase que vous obtenez de GetCurrentMethod, c'est-à-dire

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

string fullMethodName = className + "." + methodName;
59
Ruben

Et pour obtenir le nom complet de la méthode avec des paramètres:

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()));
19
mms

En prolongeant celui de Ruben, vous pouvez obtenir le nom complet comme ceci:

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

Vous pouvez l'ajouter à une méthode statique qui reçoit un paramètre MethodBase et génère la chaîne.

6
JoanComasFdz

Je pense que ces jours-ci, il est préférable de faire ceci:

string fullMethodName = $"{typeof(MyClass).FullName}.{nameof(MyMethod)}";
6
Peter Kottas

En C # 6, vous pouvez utiliser nameof:

string myName = nameof(MyMethod);
4
Salar

Vous pouvez obtenir le nom complet comme ceci:

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

Merci pour les articles ci-dessus, ils m'ont aidé à créer un système de liaison de type fort pour MVC 4 HTMLHelpers comme suit.

 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;

    }

Pour utiliser le code ci-dessus dans n’importe quelle vue CSHTML:

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

Cela me permet de lier n'importe quelle propriété d'un ViewModel à n'importe quel type d'élément HTML que je veux. Dans l'exemple ci-dessus, je lie le champ de nom pour les données sélectionnées postées après que l'utilisateur a effectué sa sélection. Le modèle de vue après la publication affiche automatiquement la valeur sélectionnée.

2
John Peters

Vous aurez des problèmes lors de l'exécution à l'intérieur de méthodes asynchrones. Voici comment résoudre ce problème: 

Si vous devez qualifier complètement le nom de la classe, vous devrez utiliser DeclaringType.FullName au lieu de DeclaringType.Name.

Ce code ne fonctionnera pas bien pour les méthodes anonymes ou 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;
    }
}

Voici un exemple d'utilisation: 

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