Comprendre la chaîne dappels [fermé]

Clôturé. Cette question est hors sujet . Il naccepte pas les réponses actuellement.

Commentaires

  • il ny a pas dhéritage ou quoi que ce soit entre ces classes non plus.
  • Une simple réflexion vous indiquera à tout moment votre méthode dappel actuelle . Vous navez ' pas besoin dune trace de pile complète pour cela. Cette question appartient probablement à StackOverflow.
  • @JimmyHoffa La question est à la recherche de moyens génériques OO de le faire (contrairement à la version initiale de ma réponse ci-dessous).
  • Pourriez-vous faire assemblyA et assemblyB hérite de assemblyC afin quils aient tous les deux accès à cette méthode? Ou, MethodFoo () pourrait-il être rendu statique pour que vous ' t réellement besoin de créer un objet de cette classe pour lappeler?
  • pourquoi auriez-vous besoin de ? si vous avez besoin dun comportement différent, créez différentes méthodes ou passez un paramètre

Answer

Je ne connais aucun générique ou des modèles communs dans les langages de programmation. La plupart le gèrent par des API de réflexion dédiées.

Dans .Net, utilisez System.Diagnostics.StackFrame et Classes System.Diagnostics.StackTrace . Consultez https://stackoverflow.com/questions/12556767/how-to-get-current-line-number-for-example-use-at-messagebox-show/12556789#12556789 pour un exemple. Dautres langages et environnements peuvent avoir des équivalents.

Commentaires

  • Oui, mais y a-t-il un moyen orienté objet de résoudre ce problème? donc pour éviter StackTrace
  • @BDotA: Si vous vous souciez de qui vous a appelé, vous ' ne faites pas de POO. Repensez ce que vous êtes essayer de faire. (Jadmets que .NET nest souvent pas OO et que nous devons parfois laisser OO derrière nous lors de son utilisation, mais il est utile de savoir que nous ' re faire cela, même si nous devons le faire de toute façon.)

Réponse

Je vais continuer un membre ici et je suppose que vous cherchez des techniques orientées objet pour implémenter linstrumentation.

Il y a deux façons immédiates qui me viennent à lesprit, la plus couramment utilisée serait la première que je devine:

  1. Avoir une pile globale (singleton ou quoi que ce soit) quelque part avec laquelle chaque méthode qui s’exécute s’ajoute immédiatement à. maintenir efficacement une chaîne d’appels globale. à la fin de chaque méthode que vous essayez dinstrumenter, dautres pratiques dinstrumentation courantes consistent à démarrer un chronomètre au début de votre méthode et à sarrêter à la fin pour enregistrer la durée, etc.

  2. Avoir un cadre de type DI qui est un routeur pour tous les appels de méthode, ce qui pourrait e plus proche du passage de message, et à lintérieur de ce cadre, vous noteriez dans une pile chaque appel de méthode qui se produit comme ci-dessus sauf quil serait centralisé à cet endroit.

Je ne peux pas dire que je suggère # 2 sans peut-être utiliser un framework AOP ou quelque chose du genre, mais dans lensemble, maintenir votre propre trace de pile sur 100% des appels de méthode est un peu une instrumentation extrême à mes yeux. Idéal pour déboguer des trucs de type et peut-être nécessaire si vous ne travaillez pas dans un langage réflexif, mais je serais sûr que je pourrais désactiver nimporte quoi de ce genre facilement pour la production et faire de mon mieux pour le garder à lécart, cest pourquoi je Je naime pas vraiment # 2 ci-dessus.

Aucun de ces éléments nest nécessaire dans un langage réflexif et ne doit donc pas être implémenté en C # sauf pour illustrer le processus de croisement (mise en garde: elles pourraient être plus rapides que la réflexion si elles sont bien faites, mais le coût de maintenance nen vaut toujours pas la peine)

Commentaires

  • Merci pour les idées, alors en C # comment puis-je le faire avec Reflection? Je ne sais pas si je peux déplacer ce message vers SO? ou copiez-collez et créez un nouveau message dans SO une bonne idée … donc si vous pouviez maider avec Reflection, ce serait génial.
  • @BDotA Regardez stackoverflow.com/questions/171970/ … bien que je pensais avoir rappelé un moyen sans invoquer lobjet StackFrame I ' je nai pas pu le trouver Même si les techniques ci-dessus ne doivent pas être effectuées en C #, utilisez plutôt la StackFrame si nécessaire.

Réponse

À mon humble avis, vous devriez vous demander sérieusement pourquoi vous pensez avoir besoin de cela.

Si MethodFoo() se comporte différemment sil est appelé depuis lassembly A ou B, alors lassembly appelant est quelque chose comme un paramètre dentrée masqué à MethodFoo() et peut probablement devenir la cause dun comportement inattendu ou erroné.Donc, comme alternative, rendez ce paramètre dentrée explicite: ajoutez un paramètre supplémentaire à MethodFoo() qui indique le contexte ou lappelant. Il peut sagir dun enum, dun paramètre string ou dune référence à lassembly appelant lui-même, selon le changement de comportement prévu de MethodFoo().

Commentaires

  • Oh mon Dieu, je nai pas ' t imaginez même quil essayait de contrôler le flux, que ' est une pensée très effrayante … Vous êtes clairement beaucoup plus pessimiste que moi pour arriver à cette conclusion, mais malheureusement peut-être raison ..
  • @JimmyHoffa: si quelquun pose une question comme celle-ci sans rien dire sur son intention, je me méfie 😉

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *