Posso obter a instância chamando de dentro de um método através de reflexão / diagnóstico?

StackOverflow https://stackoverflow.com/questions/97193

  •  01-07-2019
  •  | 
  •  

Pergunta

Existe uma maneira via System.Reflection, System.Diagnostics ou outro para obter uma referência à instância real que está chamando um método estático sem passá-la para o próprio método?

Por exemplo, algo ao longo destas linhas

class A
{
    public void DoSomething()
    {
        StaticClass.ExecuteMethod();
    }
}

class B
{
    public void DoSomething()
    {
        SomeOtherClass.ExecuteMethod();
    }
}
public class SomeOtherClass
{
    public static void ExecuteMethod()
    {
        // Returns an instance of A if called from class A
        // or an instance of B if called from class B.
        object caller = getCallingInstance();
    }
}

posso obter o tipo usando System.Diagnostics. StackTrace.GetFrames , mas há uma maneira de obter uma referência à instância real?

Estou ciente dos problemas com reflexão e desempenho, bem como estática para chamadas estáticas, e que esta é geralmente, talvez até quase univerally, não a maneira correta de abordar este. Parte da razão desta pergunta é que eu estava curioso para saber se era factível; atualmente estamos passando a instância no.

ExecuteMethod(instance)

E eu só queria saber se isso era possível e ainda ser capaz de acessar a instância.

ExecuteMethod()

@ Steve Cooper: Eu não tinha considerado os métodos de extensão. Alguma variação desse trabalho poder.

Foi útil?

Solução

Eu não acredito que você pode. Mesmo as classes Stacktrace e StackFrame apenas dar-lhe informações nomeação, não acesso a instâncias.

Eu não sei exatamente por que você iria querer fazer isso, mas sei que mesmo se você poderia fazê-lo, provavelmente, seria muito lento.

A melhor solução seria para empurrar a instância a um contexto local fio antes de chamar ExecuteMethod que você pode recuperar dentro dela ou apenas passar a instância.

Outras dicas

Considere fazer o método um método de extensão. Defini-lo como:

public static StaticExecute(this object instance)
{
    // Reference to 'instance'
}

Ele é chamado como:

this.StaticExecute();

Eu não consigo pensar em uma maneira de fazer o que você quer fazer diretamente, mas eu só posso sugerir que se você encontrar alguma coisa, você atente para métodos estáticos, que não terá um, e métodos anônimos, que terão instâncias de classes geradas automaticamente, o que será um pouco estranho.

Eu me pergunto se você deve apenas passar o objeto de chamada como um parâmetro adequado. Afinal, um static é um indício de que este método não depende de nada além de seus parâmetros de entrada. Observe também que este método pode ser uma cadela para teste, como qualquer código de teste que você escreve não terá o mesmo objeto invocando como o sistema de execução.

No caso de um método estático chamando seu método estático, não há nenhuma instância chamando.

Encontre uma maneira diferente de realizar tudo o que você está tentando fazer.

Basta ter ExecuteMethod pegar um objeto. Então você tem a instância não importa o que.

Eu sinto como se estivesse faltando alguma coisa, aqui. O método estático pode ser chamado de literalmente em qualquer lugar. Não há nenhuma garantia de que uma classe A ou instância de classe B vai aparecer em qualquer lugar na pilha de chamadas.

Tem que haver uma maneira melhor de realizar o que você está tentando fazer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top