De oproepketen uitzoeken [closed]

Gesloten. Deze vraag is off-topic . Het accepteert momenteel geen antwoorden.

Reacties

  • er is ook geen overerving of iets tussen deze klassen.
  • Eenvoudige reflectie zal je op elk moment vertellen wat je huidige methode is die de methode aanroept . Je hebt hiervoor geen ' een volledige stacktrace nodig. Deze vraag hoort waarschijnlijk op StackOverflow.
  • @JimmyHoffa De vraag is op zoek naar generieke OO-manieren om dit te doen (in tegenstelling tot de eerste versie van mijn antwoord hieronder).
  • Kun je assemblyA en assemblyB erven van assemblyC zodat ze allebei toegang hebben tot deze methode? Of zou MethodFoo () statisch gemaakt kunnen worden zodat je ' niet echt een object van die klasse hoeft te maken om het te noemen?
  • waarom zou je dat moeten doen? ? als je ander gedrag nodig hebt, maak dan verschillende methoden of geef een parameter door.

Answer

Ik ken geen generieke of gemeenschappelijke patronen in programmeertalen. De meeste verwerken het door speciale reflectie-APIs.

Gebruik in .Net de System.Diagnostics.StackFrame en System.Diagnostics.StackTrace klassen. Zie https://stackoverflow.com/questions/12556767/how-to-get-current-line-number-for-example-use-at-messagebox-show/12556789#12556789 voor een voorbeeld. Andere talen en omgevingen kunnen equivalenten hebben.

Opmerkingen

  • Ja, maar is er een objectgeoriënteerde manier om dit op te lossen? dus om StackTrace te vermijden
  • @BDotA: Als het je kan schelen wie je heeft gebeld, ' doe je geen OOP. Heroverweeg wat je bent proberen te doen. (Ik geef toe, .NET is vaak geen OO en we moeten OO soms achterlaten wanneer we het gebruiken, maar het loont de moeite om te weten dat we ' opnieuw dit doen, zelfs als we het toch moeten doen.)

Antwoord

Ik ga op pad een ledemaat hier en je vermoedt dat je op zoek bent naar objectgeoriënteerde technieken voor het implementeren van instrumentatie.

Er zijn twee onmiddellijke manieren die in je opkomen, de meest gebruikte zijn de eerste die ik vermoed:

  1. Zorg dat je ergens een globale (singleton of wat heb je) stack hebt waarmee elke methode die wordt uitgevoerd, zichzelf onmiddellijk toevoegt aan het effectief onderhouden van een globale oproepketen. Je hoeft maar niet naar de einde van elke methode die u probeert te instrumenteren, gebruikelijke andere instrumentatiepraktijken zijn om een stopwatch aan het begin van uw methode te starten en aan het einde te stoppen om de lengte enz. op te nemen.

  2. Heb een DI-type framework dat een router is voor alle methodeaanroepen, die zich kunnen gedragen Het lijkt meer op het doorgeven van berichten, en binnen dit raamwerk zou je elke methodeaanroep die op dezelfde manier voorkomt als hierboven in een stapel noteren, behalve dat het gecentraliseerd zou zijn op deze ene plek.

Ik kan niet zeggen dat ik # 2 suggereer zonder misschien een AOP-framework of zoiets te gebruiken, maar al met al is het onderhouden van je eigen stacktracering op 100% van de methodeaanroepen een beetje een extreme instrumentatie in mijn ogen. Geweldig voor het debuggen van dingen en misschien nodig als je niet in een reflexieve taal werkt, maar ik zou er zeker van zijn dat ik zoiets gemakkelijk zou kunnen uitschakelen voor productie en mijn best zou doen om het uit de weg te houden. vind # 2 hierboven niet echt leuk.

Geen van beide is nodig in een reflexieve taal en mag daarom niet in C # worden geïmplementeerd, behalve om het kruisingsproces te illustreren grenzen. (waarschuwing: ze kunnen sneller zijn dan reflectie als ze goed worden gedaan, maar de onderhoudskosten maken ze het nog steeds niet waard)

Reacties

  • Bedankt voor de ideeën, dus in C # hoe kan ik dat doen met Reflection? Ik weet niet of ik dit bericht naar SO kan verplaatsen? of kopieer en plak en maak een nieuw bericht in SO een goed idee … dus als je me zou kunnen helpen met Reflection zou het geweldig zijn.
  • @BDotA Kijk naar stackoverflow.com/questions/171970/ … hoewel ik dacht dat ik me een manier herinnerde zonder het StackFrame -object I heb ' t niet kunnen vinden. Zelfs dan zouden de bovenstaande technieken niet in C # moeten worden gedaan, in plaats daarvan zou u de StackFrame moeten gebruiken indien nodig.

Antwoord

IMHO je moet jezelf serieus afvragen waarom je denkt dat je dit nodig hebt.

Als MethodFoo() zich anders gedraagt als het wordt aangeroepen vanuit assembly A of B, dan is de aanroepende assembly zoiets als een verborgen invoerparameter voor MethodFoo() en kan waarschijnlijk de oorzaak worden van onverwacht of foutief gedrag.Dus als alternatief, maak die invoerparameter expliciet: voeg een extra parameter toe aan MethodFoo() die de context of aanroeper aangeeft. Dit kan een enum, een string -parameter zijn of een verwijzing naar de aanroepende assembly zelf, afhankelijk van de beoogde gedragsverandering van MethodFoo().

Reacties

  • Oh jee, dat heb ik niet ' t stel je zelfs voor dat hij de stroom probeerde te beheersen, dat ' een heel beangstigende gedachte is … Het is duidelijk dat je veel pessimistischer bent dan ik om tot die conclusie te komen, maar helaas kan gelijk hebben ..
  • @JimmyHoffa: als iemand een vraag als deze stelt zonder iets over zijn bedoeling te vermelden, word ik achterdochtig 😉

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *