2009-06-11 16 views
4

Gibt es in C# eine Möglichkeit für eine Klasse oder Methode zu wissen, wer (d. H. Welche Klasse/Methode) sie aufgerufen hat?Herausfinden, welche Klasse eine Methode aufgerufen hat

Zum Beispiel könnte ich

class a{ 
    public void test(){ 
     b temp = new b(); 
     string output = temp.run(); 
    } 
} 

class b{ 
    public string run(){ 
     **CODE HERE** 
    } 
} 

Ausgang habe: "Ausgeführt durch die 'Test' Methode der Klasse 'a'."

+1

Bitte nutze diese Kraft für gut, nicht böse. –

Antwort

13

StackFrame-

var frame = new StackFrame(1); 

Console.WriteLine("Called by method '{0}' of class '{1}'", 
    frame.GetMethod(), 
    frame.GetMethod().DeclaringType.Name); 
+1

Ja, das scheint genau die Lösung zu sein. Nur um es zu verdeutlichen: 'new StackFrame (1)' gibt den Stack-Frame auf einer Ebene vom aktuellen (aktiven) Frame zurück. – Noldorin

+0

Wusste nicht die nette Überladung ... +1 –

2

Sie können den Stack-Trace betrachten, um festzustellen, wer ihn aufgerufen hat.

http://msdn.microsoft.com/en-us/library/system.environment.stacktrace.aspx

+2

StackTrace bietet nicht garantiert eine vollständige Stack-Trace, nur eine Annäherung. Weitere Informationen finden Sie in den Hinweisen unter http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx. Siehe auch http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx für Beispiele, wo das NoInlining-Attribut Ihnen nicht helfen wird. Die Tatsache, dass bestimmte Optimierungen im 64-Bit- und nicht im 32-Bit-Modus auftreten, ist ein Implementierungsdetail des JITter und kann ohne Warnung geändert werden. – Levi

+0

Das ist eigentlich ziemlich interessant. Ich gehe davon aus, dass der Grund für die Notwendigkeit, zu wissen, welche Klasse eine Funktion aufgerufen wird, nur für das Debugging sein wird, wofür dies wahrscheinlich nützlich sein wird. Aber wenn das für die Anwendungslogik verwendet wird, dann ist es sowieso eine schlechte Idee wegen der Performance. – Nippysaurus

0

StackFrame wird es tun, wie Jimmy vorschlug. Vorsicht bei der Verwendung von StackFrame jedoch. Die Instanziierung ist ziemlich kostspielig, und abhängig davon, wo genau Sie es instanziieren, müssen Sie möglicherweise MethodImplOptions.NoInlining angeben. Wenn du den Stack-Walk einpacken willst, um den Caller des Callers in einer praktischen Funktion zu finden, musst du folgendes tun:

[MethodImpl(MethodImplOptions.NoInlining)] 
public static MethodBase GetThisCaller() 
{ 
    StackFrame frame = StackFrame(2); // Get caller of the method you want 
             // the caller for, not the immediate caller 
    MethodBase method = frame.GetMethod(); 
    return method; 
} 
Verwandte Themen