Comentários
- também não há herança ou nada entre essas classes.
- A reflexão simples dirá a qualquer momento seus métodos atuais de chamada de método . Você não ' não precisa de um rastreamento de pilha completo para isso. Esta pergunta provavelmente pertence ao StackOverflow.
- @JimmyHoffa A questão é procurar maneiras genéricas OO de fazer isso (ao contrário da versão inicial da minha resposta abaixo).
- Você poderia fazer assemblyA e assemblyB herda de assemblyC para que ambos tenham acesso a esse método? Ou o MethodFoo () poderia ser estático para que você não ' realmente precise fazer um objeto dessa classe para chamá-lo?
- por que você precisaria ? se precisar de um comportamento diferente, crie métodos diferentes ou passe um parâmetro
Resposta
Não conheço nenhum genérico ou padrões comuns em linguagens de programação. A maioria lida com isso por APIs de reflexão dedicadas.
Em .Net use o System.Diagnostics.StackFrame e Classes System.Diagnostics.StackTrace . Consulte https://stackoverflow.com/questions/12556767/how-to-get-current-line-number-for-example-use-at-messagebox-show/12556789#12556789 para obter um exemplo. Outras linguagens e ambientes podem ter equivalentes.
Comentários
- Sim, mas existe uma maneira orientada a objetos de resolver isso? então, para evitar StackTrace
- @BDotA: Se você se importa com quem ligou, você ' não está fazendo OOP. Repense o que você é tentando fazer. (Eu admito, o .NET geralmente não é OO e temos que deixar o OO para trás às vezes ao usá-lo, mas vale a pena saber que nós ' re fazendo isso, mesmo que tenhamos que fazer de qualquer maneira.)
Resposta
Estou saindo um membro aqui e suponho que você está procurando por técnicas orientadas a objetos para implementar instrumentação.
Existem duas maneiras imediatas que vêm à mente, a mais comumente usada seria a primeira que estou supondo:
-
Tenha uma pilha global (singleton ou o que quer que seja) em algum lugar com a qual cada método que executa imediatamente se adiciona. efetivamente mantendo uma cadeia de chamadas global. Você não poderia, mas não tem que ir até o final de cada método que você está tentando instrumentar, outras práticas comuns de instrumentação são iniciar um cronômetro no início de seu método e parar no final para registrar a duração, etc.
-
Ter uma estrutura do tipo DI que é um roteador para todas as chamadas de método, que podem se comportar e mais parecido com a passagem de mensagens, e dentro desta estrutura você anotaria em uma pilha cada chamada de método que ocorresse semelhante ao anterior, exceto que seria centralizada neste único lugar.
Eu não posso dizer que sugiro # 2 sem talvez usar algum framework AOP ou algo assim, mas em tudo, manter seu próprio rastreamento de pilha em 100% das chamadas de método é um pouco como uma instrumentação extrema aos meus olhos. Ótimo para depurar coisas do tipo e talvez necessário se você não estiver trabalhando em uma linguagem reflexiva, mas eu teria certeza de que poderia desligar qualquer coisa assim facilmente para produção e fazer o meu melhor para mantê-la fora do caminho, e é por isso que eu realmente não gosto do # 2 acima.
Nenhum dos dois é necessário dentro de uma linguagem reflexiva e, portanto, não deve ser implementado em C #, exceto para ilustrar o processo de cruzamento limites. (advertência: eles podem ser mais rápidos do que a reflexão se feitos da maneira certa, mas o custo de manutenção ainda faz com que não valham a pena)
Comentários
- Obrigado pelas ideias, então em C # como posso fazer isso com o Reflection? Não sei se posso mover este post para ASSIM? ou copie, cole e crie uma nova postagem no SO, uma boa ideia … então, se você pudesse me ajudar com o Reflection way, seria ótimo.
- @BDotA Olhe em stackoverflow.com/questions/171970/ … embora eu pensei que me lembrava de uma maneira sem invocar o
StackFrame
objeto I ainda ' não foi capaz de encontrá-lo. Mesmo assim, as técnicas acima não devem ser feitas em C #; em vez disso, você deve usar aStackFrame
se necessário.
Resposta
IMHO, você deve se perguntar seriamente por que acha que precisa disso.
Se MethodFoo()
se comportar de maneira diferente se for chamado do assembly A ou B, o assembly de chamada é algo como um parâmetro de entrada oculto para MethodFoo()
e pode provavelmente se tornar a causa de um comportamento inesperado ou incorreto.Portanto, como alternativa, torne esse parâmetro de entrada explícito: adicione um parâmetro adicional a MethodFoo()
que indica o contexto ou chamador. Isso pode ser um enum
, um string
parâmetro ou uma referência ao próprio assembly de chamada, dependendo da mudança de comportamento pretendida de MethodFoo()
.
Comentários
- Nossa, eu não ' t imagine que ele estava tentando controlar o fluxo, que ' é um pensamento muito assustador … Obviamente você é muito mais pessimista do que eu para chegar a essa conclusão, mas infelizmente você pode estar certo ..
- @JimmyHoffa: se alguém fizer uma pergunta como esta sem mencionar nada sobre sua intenção, fico desconfiado 😉