Comme le dit le titre: La réflexion peut-elle vous donner le nom de la méthode en cours d'exécution.
J'ai tendance à ne pas deviner, à cause du problème de Heisenberg. Comment appelez-vous une méthode qui vous indiquera la méthode actuelle sans changer ce qu'est la méthode actuelle? Mais j'espère que quelqu'un pourra me prouver le contraire.
Mettre à jour:
- Partie 2: Cela pourrait-il également être utilisé pour rechercher dans le code d'une propriété?
- Partie 3: À quoi ressemblerait la performance?
Résultat final
J'ai appris sur MethodBase.GetCurrentMethod (). J'ai également appris que non seulement je peux créer une trace de pile, mais je ne peux créer que le cadre exact dont j'ai besoin si je le souhaite.
Pour l'utiliser dans une propriété, prenez simplement un .Substring (4) pour supprimer le 'set_' ou le 'get_'.
.net
reflection
Joel Coehoorn
la source
la source
Réponses:
Depuis .NET 4.5, vous pouvez également utiliser [CallerMemberName]
Exemple: un configurateur de propriétés (pour répondre à la partie 2):
Le compilateur fournira des littéraux de chaîne correspondants sur les sites d'appels, il n'y a donc pratiquement pas de surcharge de performances.
la source
StackFrame(1)
méthode décrite dans d'autres réponses pour la journalisation, qui semblait fonctionner jusqu'à ce que le Jitter décide de commencer à aligner les choses. Je ne voulais pas ajouter l'attribut pour empêcher l'inline pour des raisons de performances. L'utilisation de l'[CallerMemberName]
approche a résolu le problème. Merci!OnPropertyChanged("SomeProperty")
et nonOnPropertyChanged("SetProperty")
Pour les non-
async
méthodes on peut utiliserhttps://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.getcurrentmethod
N'oubliez pas que pour les
async
méthodes, il renverra "MoveNext".la source
async
méthode, vous obtiendrez très probablement "MoveNext" comme nom de méthode.L'extrait fourni par Lex était un peu long, donc je souligne la partie importante car personne d'autre n'a utilisé exactement la même technique:
Cela devrait renvoyer des résultats identiques à la méthode MethodBase.GetCurrentMethod (). Name , mais cela vaut quand même la peine d'être souligné car je pourrais l'implémenter une fois dans sa propre méthode en utilisant l'index 1 pour la méthode précédente et l'appeler à partir d'un certain nombre de propriétés différentes. En outre, il ne renvoie qu'une seule image plutôt que la trace de la pile entière:
C'est aussi une doublure;)
la source
Essayez ceci dans la méthode Main dans un programme console vide:
Sortie console:
Main
la source
Oui définitivement.
Si vous voulez qu'un objet manipule, j'utilise en fait une fonction comme celle-ci:
Cette ligne:
Parcourt le cadre de pile pour trouver la méthode d'appel, puis nous utilisons la réflexion pour obtenir les valeurs des informations de paramètres qui lui sont transmises pour une fonction de rapport d'erreur générique. Pour obtenir la méthode actuelle, utilisez simplement le cadre de pile actuel (1) à la place.
Comme d'autres l'ont dit pour le nom actuel des méthodes, vous pouvez également utiliser:
Je préfère parcourir la pile parce que si vous regardez en interne cette méthode, cela crée tout de même un StackCrawlMark. L'adressage direct de la pile me semble plus clair
Après la 4.5, vous pouvez maintenant utiliser le [CallerMemberNameAttribute] dans le cadre des paramètres de la méthode pour obtenir une chaîne du nom de la méthode - cela peut aider dans certains scénarios (mais vraiment dans l'exemple de l'exemple ci-dessus)
Cela semblait être principalement une solution pour le support INotifyPropertyChanged où auparavant vous aviez des chaînes jonchées tout au long de votre code d'événement.
la source
Comparaison des façons d'obtenir le nom de la méthode - en utilisant une construction de synchronisation arbitraire dans LinqPad:
CODE
RÉSULTATS
réflexion réflexion
stacktrace stacktrace
inlineconstant inlineconstant
constante constante
expr e => e.expr ()
exprmember exprmember
callermember Main
Notez que les méthodes
expr
etcallermember
ne sont pas tout à fait "correctes". Et là, vous voyez une répétition d' un commentaire connexe que la réflexion est ~ 15x plus rapide que stacktrace.la source
EDIT: MethodBase est probablement un meilleur moyen d'obtenir simplement la méthode dans laquelle vous vous trouvez (par opposition à la pile d'appel entière). Je serais toujours inquiet de l'inliner cependant.
Vous pouvez utiliser un StackTrace dans la méthode:
Et le regard sur les cadres:
Cependant, sachez que si la méthode est intégrée, vous ne serez pas à l'intérieur de la méthode que vous pensez être. Vous pouvez utiliser un attribut pour empêcher l'incrustation:
la source
new StackTrace(true)
plutôtnew StackTrace(false)
. Réglage que pourtrue
provoquera la trace de la pile à atttempt capturer le nom du fichier, le numéro de ligne et etc, ce qui pourrait faire cet appel plus lent. Sinon, une belle réponseLa façon la plus simple de traiter est la suivante:
Si System.Reflection est inclus dans le bloc using:
la source
Que diriez-vous ceci:
la source
Je pense que vous devriez pouvoir obtenir cela en créant un StackTrace . Ou, comme le mentionnent @ edg et @ Lars Mæhlum , MethodBase. GetCurrentMethod ()
la source
Essaye ça...
la source
Je viens de le faire avec une classe statique simple:
puis dans votre code:
la source
la source