2008-09-18 8 views
9

¿Hay alguna forma a través de System.Reflection, System.Diagnostics u otra para obtener una referencia a la instancia real que está llamando a un método estático sin pasarlo al método en sí?¿Puedo obtener la instancia de llamada desde un método mediante reflexión/diagnóstico?

Por ejemplo, algo a lo largo de estas líneas

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(); 
    } 
} 

puedo conseguir el tipo usando System.Diagnostics.StackTrace.GetFrames, pero ¿hay una manera de obtener una referencia a la instancia real?

Soy consciente de los problemas de reflexión y rendimiento, así como de las llamadas estáticas a estáticas, y de que esto es generalmente, quizás incluso casi univeralmente, no la forma correcta de abordar esto. Parte de la razón de esta pregunta es que tenía curiosidad de si era factible; estamos pasando actualmente en la instancia.

ExecuteMethod(instance) 

Y me preguntaba si esto era posible y aún así ser capaz de acceder a la instancia.

ExecuteMethod() 

@Steve Cooper: que no había considerado métodos de extensión. Alguna variación de eso podría funcionar.

Respuesta

4

No creo que puedas. Incluso las clases StackTrace y StackFrame solo le brindan información de nombres, no acceso a las instancias.

No estoy seguro exactamente por qué querría hacer esto, pero sepa que incluso si pudiera hacerlo, probablemente sería muy lento.

Una solución mejor sería empujar la instancia a un contexto local de subproceso antes de llamar a ExecuteMethod que puede recuperar dentro o simplemente pasar la instancia.

1

Simplemente haga que ExecuteMethod tome un objeto. Entonces tienes la instancia sin importar qué.

8

Considere hacer del método un método de extensión. Definirla como:

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

Se llama así:

this.StaticExecute(); 

No puedo pensar en una manera de hacer lo que quiere hacer directamente, pero sólo puedo sugerir que si encuentras algo , tiene cuidado con los métodos estáticos, que no tienen uno, y los métodos anónimos, que tendrán instancias de clases generadas automáticamente, lo cual será un poco extraño.

Me pregunto si debería simplemente pasar el objeto que invoca como un parámetro apropiado. Después de todo, un static es una pista de que este método no depende de nada más que sus parámetros de entrada. También tenga en cuenta que este método puede ser una perra para probar, ya que cualquier código de prueba que escriba no tendrá el mismo objeto de invocación que el sistema en ejecución.

+1

Esta es una forma muy elegante de resolver este problema – ohmusama

0

Siento que me falta algo, aquí. El método estático se puede llamar desde literalmente cualquier lugar. No hay garantía de que una instancia de clase A o clase B aparezca en cualquier lugar de la pila de llamadas.

Tiene que haber una mejor manera de lograr lo que sea que esté tratando de hacer.

1

En el caso de un método estático que llame a su método estático, no hay instancia de llamada.

Encuentra una forma diferente de lograr lo que tratas de hacer.

Cuestiones relacionadas