Commenti
- non cè ereditarietà o altro tra queste classi.
- Una semplice riflessione ti dirà in qualsiasi momento i tuoi metodi correnti che chiamano il metodo . Non ' non è necessaria una traccia completa dello stack per questo. Questa domanda probabilmente appartiene a StackOverflow.
- @JimmyHoffa La domanda è alla ricerca di metodi OO generici per farlo (a differenza della versione iniziale della mia risposta di seguito).
- Potresti creare assemblyA e assemblyB eredita da assemblyC in modo che entrambi abbiano accesso a questo metodo? Oppure, MethodFoo () potrebbe essere reso statico in modo da non ' bisogno di creare un oggetto di quella classe per chiamarlo?
- perché dovresti farlo ? se hai bisogno di un comportamento diverso crea metodi diversi o passa un parametro
Risposta
Non sono a conoscenza di alcun generico o modelli comuni nei linguaggi di programmazione. La maggior parte lo gestisce tramite API di riflessione dedicate.
In .Net usa System.Diagnostics.StackFrame e System.Diagnostics.StackTrace . Vedi https://stackoverflow.com/questions/12556767/how-to-get-current-line-number-for-example-use-at-messagebox-show/12556789#12556789 per un esempio. Altri linguaggi e ambienti possono avere equivalenti.
Commenti
- Sì, ma esiste un modo orientato agli oggetti per risolvere questo problema? quindi per evitare StackTrace
- @BDotA: Se ti interessa chi ti ha chiamato, ' non stai facendo OOP. Ripensa a quello che sei cercando di fare. (Lo ammetto, .NET spesso non è OO e a volte dobbiamo lasciar perdere OO quando lo usiamo, ma vale la pena sapere che ' ri facendo questo, anche se dobbiamo farlo comunque.)
Risposta
Io “sto uscendo su un arto qui e indovino che stai cercando tecniche orientate agli oggetti per implementare la strumentazione.
Ci sono due modi immediati che mi vengono in mente, il più comunemente usato sarebbe il primo che sto indovinando:
-
Avere uno stack globale (singleton o quello che hai) da qualche parte con il quale ogni metodo che viene eseguito si aggiunge immediatamente a. mantenendo efficacemente una catena di chiamate globale. Non puoi ma non devi fare il pop al fine di ogni metodo che stai cercando di strumentare, altre pratiche di strumentazione comuni sono lavvio di un cronometro allinizio del tuo metodo e fermarsi alla fine per registrare la lunghezza ecc.
-
Avere un framework di tipo DI che sia un router per tutte le chiamate di metodo, che potrebbe comportarsi È più simile al passaggio di messaggi, e allinterno di questo framework dovresti annotare in uno stack ogni chiamata di metodo simile a quella precedente tranne che sarebbe centralizzata in questo posto.
Non posso dire di suggerire # 2 senza forse usare qualche framework AOP o qualcosa del genere, ma nel complesso, mantenere la tua traccia dello stack sul 100% delle chiamate di metodo è un po una strumentazione estrema ai miei occhi. Ottimo per il debug di cose di tipo e forse necessario se non stai lavorando in un linguaggio riflessivo, ma sarei sicuro di poter disattivare facilmente qualsiasi cosa del genere per la produzione e fare del mio meglio per tenerlo fuori mano, motivo per cui ho non mi piace molto il punto 2 sopra.
Nessuno di questi è necessario allinterno di un linguaggio riflessivo e quindi non dovrebbe essere implementato in C # se non per illustrare il processo di incrocio limiti. (avvertenza: potrebbero essere più veloci della riflessione se eseguiti correttamente, ma il costo di manutenzione non ne vale la pena)
Commenti
- Grazie per le idee, quindi in C # come posso farlo con Reflection? Non so se posso spostare questo post in COSÌ? oppure copia e incolla e crea un nuovo post in SO, una buona idea … quindi se potessi aiutarmi con Reflection, sarebbe fantastico.
- @BDotA Guarda stackoverflow.com/questions/171970/ … anche se pensavo di ricordare un modo senza richiamare loggetto
StackFrame
I rifugio ' non sono riuscito a trovarlo. Anche le tecniche di cui sopra non dovrebbero essere eseguite in C #, piuttosto dovresti usareStackFrame
se necessario.
Risposta
IMHO dovresti chiederti seriamente perché pensi di aver bisogno di questo.
Se MethodFoo()
si comporta in modo diverso se chiamato dallassembly A o B, lassembly chiamante è qualcosa come un parametro di input nascosto a MethodFoo()
e potrebbe probabilmente diventare la causa di comportamenti imprevisti o errati.Quindi, in alternativa, rendi esplicito quel parametro di input: aggiungi un parametro aggiuntivo a MethodFoo()
che indica il contesto o il chiamante. Potrebbe essere un enum
, un parametro string
o un riferimento allassembly chiamante stesso, a seconda della modifica del comportamento prevista di MethodFoo()
.
Commenti
- Oddio, non lho fatto ' t immagina anche che stesse cercando di controllare il flusso, che ' sia un pensiero molto spaventoso … Chiaramente sei molto più pessimista di me per essere arrivato a questa conclusione, ma purtroppo tu potrebbe avere ragione ..
- @JimmyHoffa: se qualcuno fa una domanda come questa senza menzionare nulla sulla sua intenzione, mi insospettisco 😉