23

How can I find the full name of a calling method in C#? I have seen solutions:

How I can get the calling methods in C#

How can I find the method that called the current method?

Get Calling function name from Called function

But they only give me the top level. Consider the example:

namespace Sandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            test();
        }

        static void test()
        {
            var stackTrace = new StackTrace();
            var methodBase = stackTrace.GetFrame(1).GetMethod();
            Console.WriteLine(methodBase.Name);
        }
    }
}

This simply outputs 'Main'. How can I get it to print 'Sandbox.Program.Main'?

It's for a simple logging framework that I am working on.


Adding onto Matzi's Answer:

Here is the solution:

namespace Sandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            test();
        }

        static void test()
        {
            var stackTrace = new StackTrace();
            var methodBase = stackTrace.GetFrame(1).GetMethod();
            var Class = methodBase.ReflectedType;
            var Namespace = Class.Namespace;         // Added finding the namespace
            Console.WriteLine(Namespace + "." + Class.Name + "." + methodBase.Name);
        }
    }
}

It produces 'Sandbox.Program.Main' like it should.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Adam Schiavone
  • 2,412
  • 3
  • 32
  • 65
  • 1
    possible duplicate of [Using System.Reflection to Get a Method's Full Name](http://stackoverflow.com/questions/2968352/using-system-reflection-to-get-a-methods-full-name) – user7116 Jul 06 '12 at 18:39

5 Answers5

34

This is something like here.

MethodBase method = stackTrace.GetFrame(1).GetMethod();
string methodName = method.Name;
string className = method.ReflectedType.Name;

Console.WriteLine(className + "." + methodName);
Community
  • 1
  • 1
Matzi
  • 13,770
  • 4
  • 33
  • 50
  • Thanks! I edited the question just to add on how I figured out to find the Namespace. – Adam Schiavone Jul 06 '12 at 18:48
  • 2
    Does not work. The method may not be the calling method but one of the ones outside - the calling method may not exist anymore, i.e. have been inlined. – TomTom Jul 06 '12 at 18:49
  • Is it possible to get nested classes also? If I made a class inside of Program, lets call it `Foo`, And I have a method in `Foo` (lets call it `Bar`) call `Program.test()` It should print `Sandbox.Program.Foo.Bar` – Adam Schiavone Jul 06 '12 at 18:56
  • @TomTom, I don't really know (as in could be very wrong!), but if it has been inlined then, in MSIL, it doesn't exist as a 'method'. I don't know how a runtime method will be able to get something that only exists before compilation. – Cor_Blimey Oct 15 '12 at 21:43
  • @Matzi - That made my life so easy. Perfect answer! – Ish Goel Sep 05 '14 at 18:34
4

I think the best way to get the full name is:

 this.GetType().FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name;

Or try this:

string method = string.Format("{0}.{1}", MethodBase.GetCurrentMethod().DeclaringType.FullName, MethodBase.GetCurrentMethod().Name);

And if you want to display the most recent function call, you can use:

StackTrace st  = new StackTrace();
StackFrame sf  = st.GetFrame(0);
var methodName = sf.GetMethod();

But if you want to display the tree of calling functions, you can do it like this:

if (st.FrameCount >1)
{
     // Display the highest-level function call
     // in the trace.
     StackFrame sf = st.GetFrame(st.FrameCount-1);
     Console.WriteLine("  Original function call at top of call stack):");
     Console.WriteLine("      {0}", sf.GetMethod());
}

For more information.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Zakaria
  • 1,055
  • 12
  • 16
  • That returns the name of the current method not the calling method as the OP wants – userSteve May 04 '18 at 13:33
  • yes, you are right, if you want to display the most recent function call, you can use: StackTrace st = new StackTrace(); st.GetFrame(0); , but if you want to display the tree of calling functions, you can do it like this: if (st.FrameCount >1) { // Display the highest-level function call // in the trace. StackFrame sf = st.GetFrame(st.FrameCount-1); Console.WriteLine(" Original function call at top of call stack):"); Console.WriteLine(" {0}", sf.GetMethod()); } https://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.getframe(v=vs.110).aspx – Zakaria May 04 '18 at 16:32
3

With this method you can reliably get the full name

    public void HandleException(Exception ex, [CallerMemberName] string caller = "")
    {
        if (ex != null)
        {
            while (ex.InnerException != null)
                ex = ex.InnerException;

            foreach (var method in new StackTrace().GetFrames())
            {
                if (method.GetMethod().Name == caller)
                {
                    caller = $"{method.GetMethod().ReflectedType.Name}.{caller}";
                    break;
                }
            }

            Console.WriteLine($"Exception: {ex.Message} Caller: {caller}()");
        }
    }
SubqueryCrunch
  • 1,325
  • 11
  • 17
0

In the System.Reflection.MethodBase method GetCurrentMethod, you can find full information about the call stack using classes, etc.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
burning_LEGION
  • 13,246
  • 8
  • 40
  • 52
  • 1
    How? [`GetCurrentMethod`](https://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getcurrentmethod(v=vs.110).aspx) returns a [`MethodBase`](https://msdn.microsoft.com/en-us/library/system.reflection.methodbase(v=vs.110).aspx) which doesn't seem to expose anything about the stack trace (except the current type). – c24w Apr 07 '17 at 14:14
0

The current calling namespace which is not equal as the current namespace:

    var mNamespace = new StackTrace().GetFrames()?.Select(x =>
                {
                    try
                    {
                        return x.GetMethod().ReflectedType?.Namespace;
                    }
                    catch (Exception)
                    {
                        return string.Empty;
                    }
                }).First(x => x != new StackTrace().GetFrame(0).GetMethod().ReflectedType?.Namespace);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
tom nobleman
  • 366
  • 3
  • 8