Lors de la connexion en C #, comment puis-je connaître le nom de la méthode qui a appelé la méthode actuelle? Je sais tout System.Reflection.MethodBase.GetCurrentMethod()
, mais je veux aller plus loin dans la trace de la pile. J'ai envisagé d'analyser la trace de la pile, mais j'espère trouver un moyen plus clair et plus explicite, quelque chose comme Assembly.GetCallingAssembly()
mais pour les méthodes.
c#
.net
logging
stack-trace
system.diagnostics
flipdoubt
la source
la source
StackTrace
,StackFrame
etCallerMemberName
) et publié les résultats sous forme de résumé pour que d'autres puissent les voir ici: gist.github.com/wilson0x4d/7b30c3913e74adf4ad99b09163a57a1fRéponses:
Essaye ça:
bon mot:
Il s'agit de la méthode Get Calling utilisant la réflexion [C #] .
la source
En C # 5, vous pouvez obtenir ces informations en utilisant les informations de l' appelant :
Vous pouvez également obtenir le
[CallerFilePath]
et[CallerLineNumber]
.la source
[CallerTypeName]
été supprimé du framework .Net actuel (4.6.2) et du Core CLRVous pouvez utiliser les informations sur l'appelant et les paramètres facultatifs:
Ce test illustre cela:
Bien que StackTrace fonctionne assez rapidement ci-dessus et ne soit pas un problème de performances dans la plupart des cas, les informations sur l'appelant sont encore beaucoup plus rapides. Dans un échantillon de 1000 itérations, je l'ai cadencé 40 fois plus vite.
la source
CachingHelpers.WhoseThere("wrong name!");
==>"wrong name!"
car leCallerMemberName
is ne remplace que la valeur par défaut.this
paramètre explicite dans une méthode d'extension. De plus, Olivier a raison, vous pouvez passer une valeur et[CallerMemberName]
n'est pas appliqué; au lieu de cela, il fonctionne comme un remplacement où la valeur par défaut serait normalement utilisée. En fait, si nous regardons l'IL, nous pouvons voir que la méthode résultante n'est pas différente de ce qui aurait normalement été émis pour un[opt]
arg, l'injection deCallerMemberName
est donc un comportement CLR. Enfin, la documentation: "Les attributs des informations sur l'appelant [...] affectent la valeur par défaut transmise lorsque l'argument est omis "async
convivial quiStackFrame
ne vous aidera pas. N'affecte pas non plus l'appel d'une lambda.Un récapitulatif rapide des 2 approches avec comparaison de vitesse étant la partie importante.
http://geekswithblogs.net/BlackRabbitCoder/archive/2013/07/25/c.net-little-wonders-getting-caller-information.aspx
Déterminer l'appelant au moment de la compilation
Déterminer l'appelant à l'aide de la pile
Comparaison des 2 approches
la source
Nous pouvons améliorer un peu le code de M. Assad (la réponse actuellement acceptée) en instanciant uniquement le cadre dont nous avons réellement besoin plutôt que la pile entière:
Cela pourrait fonctionner un peu mieux, mais selon toute vraisemblance, il doit encore utiliser la pile complète pour créer cette seule image. En outre, il a toujours les mêmes mises en garde qu'Alex Lyman a souligné (l'optimiseur / code natif pourrait corrompre les résultats). Enfin, vous voudrez peut-être vérifier pour être sûr que
new StackFrame(1)
ou.GetFrame(1)
ne revenez pasnull
, aussi improbable que cela puisse paraître.Voir cette question connexe: pouvez-vous utiliser la réflexion pour trouver le nom de la méthode en cours d'exécution?
la source
new ClassName(…)
égal à null?En général, vous pouvez utiliser la
System.Diagnostics.StackTrace
classe pour obtenir unSystem.Diagnostics.StackFrame
, puis utiliser laGetMethod()
méthode pour obtenir unSystem.Reflection.MethodBase
objet. Cependant, il y a quelques mises en garde à cette approche:( REMARQUE: je développe simplement la réponse fournie par Firas Assad .)
la source
Depuis .NET 4.5, vous pouvez utiliser les attributs d' informations sur l'appelant :
CallerFilePath
- Le fichier source qui a appelé la fonction;CallerLineNumber
- Ligne de code qui a appelé la fonction;CallerMemberName
- Membre qui a appelé la fonction.Cette fonctionnalité est également présente dans ".NET Core" et ".NET Standard".
Références
CallerFilePathAttribute
ClasseCallerLineNumberAttribute
ClasseCallerMemberNameAttribute
Classela source
Notez que cela ne sera pas fiable dans le code de version, en raison de l'optimisation. De plus, l'exécution de l'application en mode sandbox (partage réseau) ne vous permettra pas du tout de saisir le cadre de la pile.
Considérez la programmation orientée aspect (AOP), comme PostSharp , qui au lieu d'être appelée à partir de votre code, modifie votre code et sait ainsi où il se trouve à tout moment.
la source
Évidemment, c'est une réponse tardive, mais j'ai une meilleure option si vous pouvez utiliser .NET 4.5 ou plus:
Cela affichera la date et l'heure actuelles, suivies de "Namespace.ClassName.MethodName" et se terminant par ": text".
Exemple de sortie:
Exemple d'utilisation:
la source
la source
Peut-être que vous cherchez quelque chose comme ça:
la source
Une classe fantastique est ici: http://www.csharp411.com/c-get-calling-method/
la source
Une autre approche que j'ai utilisée consiste à ajouter un paramètre à la méthode en question. Par exemple, au lieu de
void Foo()
, utilisezvoid Foo(string context)
. Passez ensuite une chaîne unique qui indique le contexte d'appel.Si vous n'avez besoin que de l'appelant / du contexte pour le développement, vous pouvez supprimer le
param
avant l'expédition.la source
Pour obtenir le nom de la méthode et le nom de la classe, essayez ceci:
la source
sera suffisant, je pense.
la source
Jetez un œil au nom de la méthode de journalisation dans .NET . Méfiez-vous de l'utiliser dans le code de production. StackFrame n'est peut-être pas fiable ...
la source
Nous pouvons également utiliser des lambda pour trouver l'appelant.
Supposons que vous ayez défini une méthode:
et vous voulez trouver son appelant.
1 . Modifiez la signature de la méthode pour avoir un paramètre de type Action (Func fonctionnera également):
2 . Les noms lambda ne sont pas générés de manière aléatoire. La règle semble être:> <CallerMethodName> __X où CallerMethodName est remplacé par la fonction précédente et X est un index.
3 . Lorsque nous appelons MethodA, le paramètre Action / Func doit être généré par la méthode de l'appelant. Exemple:
4 . À l'intérieur de MethodA, nous pouvons maintenant appeler la fonction d'assistance définie ci-dessus et trouver le MethodInfo de la méthode de l'appelant.
Exemple:
la source
Informations supplémentaires à la réponse de Firas Assaad.
J'ai utilisé
new StackFrame(1).GetMethod().Name;
dans .net core 2.1 avec injection de dépendances et je reçois la méthode d'appel en tant que 'Start'.J'ai essayé avec
[System.Runtime.CompilerServices.CallerMemberName] string callerName = ""
et ça me donne la bonne méthode d'appella source
la source