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

后端 未结 19 1748
猫巷女王i
猫巷女王i 2020-11-21 22:50

When logging in C#, how can I learn the name of the method that called the current method? I know all about System.Reflection.MethodBase.GetCurrentMethod(), but

相关标签:
19条回答
  • 2020-11-21 23:14

    Try this:

    using System.Diagnostics;
    // Get call stack
    StackTrace stackTrace = new StackTrace(); 
    // Get calling method name
    Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
    

    one-liner:

    (new System.Diagnostics.StackTrace()).GetFrame(1).GetMethod().Name
    

    It is from Get Calling Method using Reflection [C#].

    0 讨论(0)
  • 2020-11-21 23:17

    Take a look at Logging method name in .NET. Beware of using it in production code. StackFrame may not be reliable...

    0 讨论(0)
  • 2020-11-21 23:19

    You can use Caller Information and optional parameters:

    public static string WhoseThere([CallerMemberName] string memberName = "")
    {
           return memberName;
    }
    

    This test illustrates this:

    [Test]
    public void Should_get_name_of_calling_method()
    {
        var methodName = CachingHelpers.WhoseThere();
        Assert.That(methodName, Is.EqualTo("Should_get_name_of_calling_method"));
    }
    

    While the StackTrace works quite fast above and would not be a performance issue in most cases the Caller Information is much faster still. In a sample of 1000 iterations, I clocked it as 40 times faster.

    0 讨论(0)
  • 2020-11-21 23:19

    Maybe you are looking for something like this:

    StackFrame frame = new StackFrame(1);
    frame.GetMethod().Name; //Gets the current method name
    
    MethodBase method = frame.GetMethod();
    method.DeclaringType.Name //Gets the current class name
    
    0 讨论(0)
  • 2020-11-21 23:20

    A quick recap of the 2 approaches with speed comparison being the important part.

    http://geekswithblogs.net/BlackRabbitCoder/archive/2013/07/25/c.net-little-wonders-getting-caller-information.aspx

    Determining the caller at compile-time

    static void Log(object message, 
    [CallerMemberName] string memberName = "",
    [CallerFilePath] string fileName = "",
    [CallerLineNumber] int lineNumber = 0)
    {
        // we'll just use a simple Console write for now    
        Console.WriteLine("{0}({1}):{2} - {3}", fileName, lineNumber, memberName, message);
    }
    

    Determining the caller using the stack

    static void Log(object message)
    {
        // frame 1, true for source info
        StackFrame frame = new StackFrame(1, true);
        var method = frame.GetMethod();
        var fileName = frame.GetFileName();
        var lineNumber = frame.GetFileLineNumber();
    
        // we'll just use a simple Console write for now    
        Console.WriteLine("{0}({1}):{2} - {3}", fileName, lineNumber, method.Name, message);
    }
    

    Comparison of the 2 approaches

    Time for 1,000,000 iterations with Attributes: 196 ms
    Time for 1,000,000 iterations with StackTrace: 5096 ms
    

    So you see, using the attributes is much, much faster! Nearly 25x faster in fact.

    0 讨论(0)
  • 2020-11-21 23:20

    Note that doing so will be unreliable in release code, due to optimization. Additionally, running the application in sandbox mode (network share) won't allow you to grab the stack frame at all.

    Consider aspect-oriented programming (AOP), like PostSharp, which instead of being called from your code, modifies your code, and thus knows where it is at all times.

    0 讨论(0)
提交回复
热议问题