tags:

views:

208

answers:

5

Hello :)

I'd like to write a method which obtains the name of the calling method, and the name of the class containing the calling method.

Is such a thing possible with C# reflection?

Billy3

+6  A: 

Yes, in principe it is possible, but it doesn't come for free.

You need to create a StackTrace, and then you can have a look at the StackFrame's of the call stack.

Lucero
+3  A: 

You can use it by using the StackTrace and then you can get reflective types from that.

StackTrace stackTrace = new StackTrace();           // get call stack
StackFrame[] stackFrames = stackTrace.GetFrames();  // get method calls (frames)

StackFrame callingFrame = stackFrames[1];
MethodInfo method = callingFrame.GetMethod();
Console.Write(method.Name);
Console.Write(method.DeclaringType.Name);
Aren
+10  A: 
public class SomeClass
{
    public void SomeMethod()
    {
        StackFrame frame = new StackFrame(1);
        var method = frame.GetMethod();
        var type = method.DeclaringType;
        var name = method.Name;
    }
}

Now let's say you have another class like this:

public class Caller
{
   public void Call()
   {
      SomeClass s = new SomeClass();
      s.SomeMethod();
   }
}

name will be "Call" and type will be "Caller"

BFree
Nice clean and to the point!
AieshaDot
This is as good a solution as you can get, but you need to remember that this won't necessarily return the answer you expect in release builds unless you disable JIT method inlining.
Greg Beech
@Greg Beech: True. Not a problem here because I'd not use reflection in any type of release build in any case.
Billy ONeal
+3  A: 

It's actually something that can be done using a combination of the current stack-trace data, and reflection.

public void MyMethod()
{
     StackTrace stackTrace = new System.Diagnostics.StackTrace();
     StackFrame frame = stack.GetFrames()[1];
     MethodInfo method = frame.GetMethod();
     string methodName = method.Name;
     Type methodsClass = method.DeclaringType;
}

The 1 index on the StackFrame array will give you the method which called MyMethod

ckramer
A: 

Technically, you can use StackTrace but this is very slow and will not give you the answers you expect a lot of times. This is because during release builds optimizations can occur that will remove certain method calls hence you can't be sure in release whether stacktrace is "correct" or not. Really there is no full proof/fast way of doing this in C#. You should really be asking yourself why you need this and how you can architect your application so you can do what you want without knowing which method called it.

Bishnu
@Bishnu: This is A. a debug build, and B. calls other assemblies. The time it takes to start up the other programs via System.Diagnostics.Process dwarfs anything incurred by using the StackFrame class.
Billy ONeal
I'm doing this for the purposes of autoconfiguration of a test suite.
Billy ONeal