217 votes

Pouvez-vous utiliser la réflexion pour trouver le nom de la méthode en cours d'exécution?

Comme le dit le titre: réflexion Peut vous donner le nom de la méthode d'exécution.

Je suis enclin à ne le pense pas, parce que de la de Heisenberg problème. Comment appelez-vous une méthode qui vous indiquera la méthode actuelle sans changer ce que la méthode actuelle est? Mais j'espère que quelqu'un peut me prouver le contraire.

Mise à jour:

  • Partie 2: Pourrait-il être utilisé pour regarder à l'intérieur de code pour un bien?
  • Partie 3: Quel serait le rendement?

Résultat Final
J'ai appris à propos de MethodBase.GetCurrentMethod(). J'ai aussi appris que non seulement puis-je créer une trace de la pile, je peut créer uniquement à l'image exacte j'ai besoin si je veux.

Pour utiliser ce à l'intérieur d'une propriété, il suffit de prendre un .Substring(4) pour enlever le set_ " ou "get_'.

197voto

Ed Guiness Points 21866

135voto

John Nilsson Points 4650

À partir de .NET 4.5, vous pouvez également utiliser [CallerMemberName]

Exemple: un setter de propriétés (pour répondre à la partie 2):

     protected void SetProperty<T>(T value, [CallerMemberName] string property = null)
    {
        this.propertyValues[property] = value;
        OnPropertyChanged(property);
    }

    public string SomeProperty
    {
        set { SetProperty(value); }
    }
 

Le compilateur fournira des littéraux de chaîne correspondants sur les callites, donc il n'y a pratiquement pas de surcharge de performance.

51voto

Joel Coehoorn Points 190579

L'extrait de code fourni par Lex était un peu long, donc je suis en soulignant le rôle important puisque personne d'autre a utilisé exactement la même technique:

string MethodName = new StackFrame(0).GetMethod().Name;

Cela devrait renvoyer des résultats identiques à la MethodBase.GetCurrentMethod().Nom de la technique, mais il vaut la peine de souligner, car j'ai pu mettre en œuvre cette fois dans son propre méthode à l'aide de l'index 1 pour la précédente méthode et l'appeler à partir d'un certain nombre de propriétés différentes. Aussi, il ne renvoie une image plutôt que de l'ensemble de la trace de la pile:

private string GetPropertyName()
{  //.SubString(4) strips the property prefix (get|set) from the name
    return new StackFrame(1).GetMethod().Name.Substring(4);
}

C'est un one-liner, trop ;)

19voto

Lars Mæhlum Points 4569

Essayez ceci dans la méthode Main dans un programme de console vide:

 MethodBase method = MethodBase.GetCurrentMethod();
Console.WriteLine(method.Name);
 

Sortie de console:
Main

12voto

Lex Points 351

Oui, définitivement.

Si vous souhaitez un objet à manipuler j'utilise une fonction comme ceci:

public static T CreateWrapper<T>(Exception innerException, params object[] parameterValues) where T : Exception, new()
{
    if (parameterValues == null)
    {
        parameterValues = new object[0];
    }

    Exception exception   = null;
    StringBuilder builder = new StringBuilder();
    MethodBase method     = new StackFrame(2).GetMethod();
    ParameterInfo[] parameters = method.GetParameters();
    builder.AppendFormat(CultureInfo.InvariantCulture, ExceptionFormat, new object[] { method.DeclaringType.Name, method.Name });
    if ((parameters.Length > 0) || (parameterValues.Length > 0))
    {
        builder.Append(GetParameterList(parameters, parameterValues));
    }

    exception = (Exception)Activator.CreateInstance(typeof(T), new object[] { builder.ToString(), innerException });
    return (T)exception;
}

Cette ligne:

MethodBase method     = new StackFrame(2).GetMethod();

Promenades en place la trame de pile à trouver la méthode d'appel puis nous avons utiliser la réflexion pour obtenir des informations sur le paramètre des valeurs transmises pour le générique de la fonction de rapport d'erreurs. Pour obtenir la méthode actuelle tout simplement utiliser de pile actuel cadre (1) à la place.

Comme d'autres l'ont dit pour les méthodes actuelles de nom, vous pouvez également utiliser:

MethodBase.GetCurrentMethod()

Je préfère la marche de la pile car si regarder intérieurement à cette méthode, il crée simplement un StackCrawlMark de toute façon. L'adressage de la Pile directement semble plus clair pour moi

Post 4.5 vous pouvez maintenant utiliser la [CallerMemberNameAttribute] dans le cadre de la méthode des paramètres pour obtenir une chaîne de caractères du nom de la méthode, qui peut aider dans certains scénarios (mais vraiment dans l'exemple ci-dessus)

public void Foo ([CallerMemberName] string methodName = null)

Il semble que ce soit surtout une solution pour INotifyPropertyChanged soutien là où auparavant vous aviez des chaînes éparpillées à travers votre code d'événement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X