c# - what - ¿Puedo obtener la instancia de llamada desde un método mediante reflexión/diagnóstico?
propertyinfo c# (5)
En el caso de un método estático que llame a su método estático, no hay instancia de llamada.
Encuentre una forma diferente de lograr lo que sea que intente hacer.
¿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 mismo?
Por ejemplo, algo en esta línea
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 obtener el tipo usando System.Diagnostics.StackTrace.GetFrames , pero ¿hay alguna manera de obtener una referencia a la instancia real?
Soy consciente de los problemas con la reflexión y el rendimiento, así como de las llamadas estáticas a estáticas, y de que, en general, tal vez incluso de forma casi unívoca, no es 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 la instancia en.
ExecuteMethod(instance)
Y me preguntaba si esto era posible y aún así poder acceder a la instancia.
ExecuteMethod()
@Steve Cooper: no había considerado los métodos de extensión. Alguna variación de eso podría funcionar.
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ías hacer esto, pero debes saber que incluso si pudieras hacerlo, probablemente sería muy lento.
Una mejor solución sería enviar la instancia a un contexto local de subprocesos antes de llamar a ExecuteMethod que puede recuperar dentro o simplemente pasar la instancia.
Siento que me estoy perdiendo 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 forma de lograr lo que sea que intentes hacer.
Considere hacer que el método sea un método de extensión. Definirlo 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 quieres hacer directamente, pero solo puedo sugerir que, si encuentras algo, tengas en cuenta los métodos estáticos, que no tendrán uno, y los métodos anónimos, que tendrán instancias de clases autogeneradas, lo cual será un poco extraño.
Me pregunto si debería pasar el objeto invocado como un parámetro apropiado. Después de todo, una 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.
Simplemente haga que ExecuteMethod tome un objeto. Entonces tienes la instancia sin importar qué.