2010-02-10 6 views
12

Estoy buscando un algoritmo que pueda obtener el objeto que llamó al método, dentro de ese método.Obteniendo la instancia que llamó al método en C#

Por ejemplo:

public class Class1 { 

    public void Method() { 
     //the question 
     object a = ...;//the object that called the method (in this case object1) 
     //other instructions 
    } 

} 

public class Class2 { 

    public Class2() { 
     Class1 myClass1 = new Class1(); 
     myClass1.Method(); 
    } 

    public static void Main() { 
     Class2 object1 = new Class2(); 
     //... 
    } 

} 

¿Hay alguna manera de hacer esto?

+6

Tengo una pregunta, ¿qué vas a hacer con ella una vez que la tengas? Si necesita obtener una referencia al objeto que llama, ¿por qué no simplemente pasarlo como un parámetro? – Lazarus

+0

Dupe? http://stackoverflow.com/questions/420541/is-there-any-way-to-get-a-reference-to-the-calling-object-in-c – CraigTP

+1

Tengo curiosidad: ¿cuál es el caso de uso? ¿Por qué crees que necesitas hacer esto? –

Respuesta

-2

Obviamente no sé los detalles exactos de su situación, pero esto realmente parece que necesita reconsiderar su estructura de una poco.

Esto podría hacerse fácilmente si la herencia adecuada está estructurada.

Considere buscar en una clase abstracta y clases que hereden de dicha clase abstracta. Incluso podría ser capaz de lograr lo mismo con las interfaces.

0

Puede acceder al trazado actual de la pila en el código y subir un paso. http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx

Pero como se comentó a continuación, esto le dará el método y la clase que lo llama, pero no la instancia (si es que hay una, podría ser una estática por supuesto).

+0

El problema con esto puede dar lo que se llama. No es la instancia del objeto que lo llama. –

+0

Sí, tienes razón. La pregunta se refiere a la instancia, por lo que esto no funcionará. –

0

Sería muy mal estilo desde

a) que rompería la encapsulación
b) que es imposible saber el tipo de objeto que llama en tiempo de compilación así que cualquier cosa que se hace con el objeto después, es probable que no funcione.
c) que sería más fácil/mejor si usted acaba de pasar el objeto al constructor o el método, como:

Class1 c1 = new Class1(object1); 
+3

La encapsulación es una función de idioma impuesta por el compilador. Podemos romperlo de muchas maneras en el tiempo de ejecución (por ejemplo, al usar la reflexión podemos modificar campos privados). – jason

+0

No es imposible porque rompe la encapsulación (muchas cosas son posibles). Es una * muy mala idea * por eso. :-) –

+1

Bueno, prefiero decir "No es posible" que explicar "No es una buena idea, porque ..." y luego obtener la respuesta "Sí, sí, no he escuchado tus cosas con mal estilo" y lo que sea y mi idea suena genial, así lo haré ". – dbemerlin

-3

o simplemente pasar el objeto como parámetro del método.

public void Method(object callerObject) 
{ 
.. 
} 

y llame al método:

myClass.Method(this); 

respecto, Florian

7

Aquí hay un ejemplo de cómo hacer esto ...

... 
using System.Diagnostics; 
... 

public class MyClass 
{ 
/*...*/ 
    //default level of two, will be 2 levels up from the GetCaller function. 
    private static string GetCaller(int level = 2) 
    { 
     var m = new StackTrace().GetFrame(level).GetMethod(); 

     // .Name is the name only, .FullName includes the namespace 
     var className = m.DeclaringType.FullName; 

     //the method/function name you are looking for. 
     var methodName = m.Name; 

     //returns a composite of the namespace, class and method name. 
     return className + "->" + methodName; 
    } 

    public void DoSomething() { 
     //get the name of the class/method that called me. 
     var whoCalledMe = GetCaller(); 
     //... 
    } 
/*...*/ 
}

publicar esto, porque me tomó un tiempo para encontrar lo que estaba buscando para mí. Lo estoy usando en algunos métodos de registrador estático ...

+2

Debo señalar que esto no funcionará para su necesidad, ya que quiere la instancia del objeto dado ... en cuyo caso debe volver a pensar. – Tracker1

+5

Ejecute esto en modo de lanzamiento y el compilador optimizará la pila de llamadas, lo que le causará problemas. En .NET 4.5 ahora existe el atributo 'CallerMemberName' –

+7

¡Eso es todo! Realmente desapruebo los comentarios como @Lazarus made ('¿Por qué incluso necesitas esto?) Y aún más que se les sube la votación. Necesitaba esto exactamente para ti, registrador estático llamado por muchos hilos. – Mike

Cuestiones relacionadas