Herausfinden der Anrufkette [geschlossen]

geschlossen. Diese Frage ist nicht zum Thema . Derzeit werden keine Antworten akzeptiert.

Kommentare

  • Es gibt auch keine Vererbung oder irgendetwas zwischen diesen Klassen.
  • Durch einfache Reflexion erfahren Sie zu jedem Zeitpunkt, zu welchem Zeitpunkt Ihre Methoden Methoden aufrufen . Sie benötigen dafür ' keinen vollständigen Stack-Trace. Diese Frage gehört wahrscheinlich zu StackOverflow.
  • @JimmyHoffa Die Frage sucht nach generischen OO-Methoden, um dies zu tun (im Gegensatz zur ursprünglichen Version meiner Antwort unten).
  • Könnten Sie AssemblyA und AssemblyB erbt von AssemblyC, sodass beide Zugriff auf diese Methode haben. Oder könnte MethodFoo () statisch gemacht werden, damit Sie ' kein Objekt dieser Klasse erstellen müssen, um es aufzurufen?
  • Warum sollten Sie das tun müssen? ? Wenn Sie ein anderes Verhalten benötigen, erstellen Sie verschiedene Methoden oder übergeben Sie einen Parameter.

Antwort

Mir sind keine generischen Methoden bekannt oder gemeinsame Muster in verschiedenen Programmiersprachen. Die meisten verarbeiten dies über dedizierte Reflection-APIs.

Verwenden Sie in .Net das System.Diagnostics.StackFrame und System.Diagnostics.StackTrace -Klassen. Ein Beispiel finden Sie unter https://stackoverflow.com/questions/12556767/how-to-get-current-line-number-for-example-use-at-messagebox-show/12556789#12556789 . Andere Sprachen und Umgebungen haben möglicherweise Entsprechungen.

Kommentare

  • Ja, aber gibt es eine objektorientierte Möglichkeit, dies zu lösen? Um StackTrace zu vermeiden
  • @BDotA: Wenn es Sie interessiert, wer Sie angerufen hat, machen Sie ' kein OOP. Überdenken Sie, was Sie sind versuchen zu tun. (Ich gebe zu, .NET ist oft nicht OO und wir müssen OO manchmal zurücklassen, wenn wir es verwenden, aber es lohnt sich zu wissen, dass wir ' sind Tun Sie dies, auch wenn wir es trotzdem tun müssen.)

Antwort

Ich gehe weiter Ein Glied hier und die Vermutung, dass Sie nach objektorientierten Techniken zur Implementierung von Instrumenten suchen.

Es gibt zwei unmittelbare Möglichkeiten, die mir in den Sinn kommen. Am häufigsten wird die erste verwendet, die ich vermute:

  1. Haben Sie irgendwo einen globalen Stapel (Singleton oder was haben Sie), mit dem sich jede Methode, die sofort ausgeführt wird, selbst hinzufügt. Eine globale Aufrufkette wird effektiv aufrechterhalten. Sie müssen aber nicht am Am Ende jeder Methode, die Sie zu instrumentieren versuchen, besteht eine übliche andere Instrumentierungspraxis darin, eine Stoppuhr am Anfang Ihrer Methode zu starten und am Ende anzuhalten, um die Länge usw. aufzuzeichnen.

  2. Verfügen Sie über ein DI-Framework, das ein Router für alle Methodenaufrufe ist, die sich möglicherweise verhalten Es ähnelt eher der Nachrichtenübermittlung, und innerhalb dieses Frameworks würden Sie jeden Methodenaufruf, der ähnlich wie oben auftritt, in einem Stapel notieren, außer dass er an dieser einen Stelle zentralisiert wäre.

Ich kann nicht sagen, dass ich # 2 vorschlage, ohne vielleicht ein AOP-Framework oder etwas anderes zu verwenden, aber insgesamt ist es für mich eine extreme Instrumentierung, bei 100% der Methodenaufrufe einen eigenen Stack-Trace zu führen. Hervorragend geeignet zum Debuggen von Typmaterial und möglicherweise erforderlich, wenn Sie nicht in einer reflexiven Sprache arbeiten, aber ich wäre sicher, dass ich so etwas für die Produktion einfach ausschalten und mein Bestes tun könnte, um es aus dem Weg zu räumen, weshalb ich es tue mag # 2 oben nicht wirklich.

Beides ist in einer reflexiven Sprache nicht erforderlich und sollte daher nicht in C # implementiert werden, außer um den Kreuzungsprozess zu veranschaulichen Grenzen. (Einschränkung: Sie sind möglicherweise schneller als Reflexion, wenn sie richtig ausgeführt werden, aber die Wartungskosten machen sie immer noch nicht wert)

Kommentare

  • Vielen Dank für die Ideen. Wie kann ich das in C # mit Reflection tun? Ich weiß nicht, ob ich diesen Beitrag nach SO verschieben kann. oder kopieren Sie Einfügen und erstellen Sie einen neuen Beitrag in SO eine gute Idee … Wenn Sie mir also bei der Reflexion helfen könnten, wäre das großartig.
  • @BDotA Schauen Sie sich stackoverflow.com/questions/171970/ … obwohl ich dachte, ich hätte mich an einen Weg erinnert, ohne das StackFrame Objekt I aufzurufen habe ' nicht gefunden. Trotzdem sollten die oben genannten Techniken nicht in C # ausgeführt werden, sondern Sie sollten bei Bedarf die StackFrame verwenden.

Answer

IMHO sollten Sie sich ernsthaft fragen, warum Sie denken, dass Sie dies brauchen.

Wenn sich MethodFoo() anders verhält, wenn es von Assembly A oder B aufgerufen wird, ist die aufrufende Assembly so etwas wie ein versteckter Eingabeparameter für MethodFoo() und kann wahrscheinlich die Ursache für unerwartetes oder fehlerhaftes Verhalten werden.Machen Sie diesen Eingabeparameter alternativ explizit: Fügen Sie MethodFoo() einen zusätzlichen Parameter hinzu, der den Kontext oder Aufrufer angibt. Dies kann ein enum, ein string -Parameter oder ein Verweis auf die aufrufende Assembly selbst sein, abhängig von der beabsichtigten Verhaltensänderung von MethodFoo().

Kommentare

  • Oh je, ich habe nicht ' t Stellen Sie sich sogar vor, er habe versucht, den Fluss zu kontrollieren, dass ' ein sehr beängstigender Gedanke ist … Sie sind eindeutig viel pessimistischer als ich, um zu dieser Schlussfolgerung zu kommen, aber leider Sie kann richtig sein ..
  • @JimmyHoffa: Wenn jemand eine solche Frage stellt, ohne etwas über seine Absicht zu erwähnen, werde ich misstrauisch 😉

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.