Descobrindo a cadeia de chamadas [fechado]

Fechada. Esta pergunta está fora do tópico . Atualmente não está aceitando respostas.

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:

  1. 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.

  2. 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 a StackFrame 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 😉

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *