2010-02-10 5 views
12

Ich bin auf der Suche nach einem Algorithmus, der innerhalb dieser Methode das Objekt abrufen kann, das die Methode aufgerufen hat.Abrufen der Instanz, die die Methode in aufgerufen wurde C#

Zum Beispiel:

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

} 

Gibt es eine Möglichkeit, dies zu tun?

+6

Ich habe eine Frage, was wirst du damit machen, wenn du es hast? Wenn Sie einen Verweis auf das aufrufende Objekt benötigen, dann übergeben Sie es einfach als Parameter. – Lazarus

+0

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

+1

Ich bin neugierig: Was ist der Anwendungsfall? Warum denkst du, dass du das tun musst? –

Antwort

-2

Offensichtlich ich weiß nicht, die genauen Details Ihrer Situation aber dies scheint wirklich, wie Sie Ihre Struktur ein Umdenken müssen Bit.

Dies könnte leicht getan werden, wenn die richtige Vererbung strukturiert ist.

Betrachten Sie eine abstrakte Klasse und Klassen, die von dieser abstrakten Klasse erben. Sie könnten sogar das gleiche mit Schnittstellen erreichen.

0

Sie könnten zum aktuellen Stack-Trace im Code gelangen und einen Schritt nach oben gehen.

Aber wie unten erwähnt, erhalten Sie die Methode und die Klasse, die Sie aufrufen, aber nicht die Instanz (falls es eine gibt, könnte es natürlich eine statische sein).

+0

Das Problem mit diesem wird es geben, was es nannte. Nicht die Instanz des Objekts, das sie aufruft. –

+0

Ja, Sie haben Recht. Die Frage bezieht sich auf die Instanz, also wird dies nicht funktionieren. –

0

Es wäre sehr schlechter Stil seit

a), die Verkapselung
b brechen würde), ist es unmöglich, die Art des anrufenden Objekts zur Compile-Zeit wissen, so, was Sie später mit dem Objekt zu tun, es wird wahrscheinlich nicht funktionieren.
c) es wäre einfacher/besser, wenn Sie nur das Objekt an den Konstruktor oder die Methode übergeben würde, wie:

Class1 c1 = new Class1(object1); 
+3

Encapsulation ist ein Sprachfeature, das vom Compiler erzwungen wird. Wir können es zur Laufzeit auf alle möglichen Arten zerlegen (zum Beispiel können wir mit Hilfe der Reflektion private Felder modifizieren). – jason

+0

Es ist nicht unmöglich, weil es die Kapselung bricht (viele Dinge, die möglich sind, tun das). Es ist eine * sehr schlechte Idee * deswegen. :-) –

+1

Nun, ich würde eher "Nicht möglich" sagen, als zu erklären "Es ist keine gute Idee, weil ..." und dann die Antwort bekommen "Ja, ja, ich habe deine Sachen nicht auf schlechtem Stil gehört und was auch immer und meine Idee klingt cool, also werde ich es einfach tun ". – dbemerlin

-3

oder einfach nur das Objekt als Methodenparameter übergeben.

public void Method(object callerObject) 
{ 
.. 
} 

und rufen Sie die Methode:

myClass.Method(this); 

Grüße, Florian

7

Hier ist ein Beispiel dafür, wie dies zu tun ...

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

diesen Beitrag, weil es mir eine Weile gedauert, zu finden, was ich für mich suchte. Ich verwende es in einigen statischen Logger-Methoden ...

+2

Ich sollte beachten, dass dies nicht für Ihre Bedürfnisse funktioniert, wie Sie die Instanz des gegebenen Objekts wollen ... in diesem Fall sollten Sie nachdenken. – Tracker1

+5

Führen Sie dies im Freigabemodus aus, und der Compiler optimiert den Callstack, wodurch Sie Probleme bekommen. In .NET 4.5 gibt es jetzt das 'CallerMemberName' Attribut –

+7

Das war's! Ich lehne Kommentare wie @Lazarus ('Warum brauchst du das überhaupt') und noch mehr, dass sie aufgeputscht werden, wirklich ab. Ich brauchte das für genau dasselbe wie du, ein statischer Logger, der von vielen Threads aufgerufen wird. – Mike

Verwandte Themen