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

后端 未结 19 1707
猫巷女王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 22:55

    As of .NET 4.5 you can use Caller Information Attributes:

    • CallerFilePath - The source file that called the function;
    • CallerLineNumber - Line of code that called the function;
    • CallerMemberName - Member that called the function.

      public void WriteLine(
          [CallerFilePath] string callerFilePath = "", 
          [CallerLineNumber] long callerLineNumber = 0,
          [CallerMemberName] string callerMember= "")
      {
          Debug.WriteLine(
              "Caller File Path: {0}, Caller Line Number: {1}, Caller Member: {2}", 
              callerFilePath,
              callerLineNumber,
              callerMember);
      }
      

     

    This facility is also present in ".NET Core" and ".NET Standard".

    References

    1. Microsoft - Caller Information (C#)
    2. Microsoft - CallerFilePathAttribute Class
    3. Microsoft - CallerLineNumberAttribute Class
    4. Microsoft - CallerMemberNameAttribute Class
    0 讨论(0)
  • 2020-11-21 22:55
    StackFrame caller = (new System.Diagnostics.StackTrace()).GetFrame(1);
    string methodName = caller.GetMethod().Name;
    

    will be enough, I think.

    0 讨论(0)
  • 2020-11-21 22:55

    We can also use lambda's in order to find the caller.

    Suppose you have a method defined by you:

    public void MethodA()
        {
            /*
             * Method code here
             */
        }
    

    and you want to find it's caller.

    1. Change the method signature so we have a parameter of type Action (Func will also work):

    public void MethodA(Action helperAction)
            {
                /*
                 * Method code here
                 */
            }
    

    2. Lambda names are not generated randomly. The rule seems to be: > <CallerMethodName>__X where CallerMethodName is replaced by the previous function and X is an index.

    private MethodInfo GetCallingMethodInfo(string funcName)
        {
            return GetType().GetMethod(
                  funcName.Substring(1,
                                    funcName.IndexOf("&gt;", 1, StringComparison.Ordinal) - 1)
                  );
        }
    

    3. When we call MethodA the Action/Func parameter has to be generated by the caller method. Example:

    MethodA(() => {});
    

    4. Inside MethodA we can now call the helper function defined above and find the MethodInfo of the caller method.

    Example:

    MethodInfo callingMethodInfo = GetCallingMethodInfo(serverCall.Method.Name);
    
    0 讨论(0)
  • 2020-11-21 22:56
    /// <summary>
    /// Returns the call that occurred just before the "GetCallingMethod".
    /// </summary>
    public static string GetCallingMethod()
    {
       return GetCallingMethod("GetCallingMethod");
    }
    
    /// <summary>
    /// Returns the call that occurred just before the the method specified.
    /// </summary>
    /// <param name="MethodAfter">The named method to see what happened just before it was called. (case sensitive)</param>
    /// <returns>The method name.</returns>
    public static string GetCallingMethod(string MethodAfter)
    {
       string str = "";
       try
       {
          StackTrace st = new StackTrace();
          StackFrame[] frames = st.GetFrames();
          for (int i = 0; i < st.FrameCount - 1; i++)
          {
             if (frames[i].GetMethod().Name.Equals(MethodAfter))
             {
                if (!frames[i + 1].GetMethod().Name.Equals(MethodAfter)) // ignores overloaded methods.
                {
                   str = frames[i + 1].GetMethod().ReflectedType.FullName + "." + frames[i + 1].GetMethod().Name;
                   break;
                }
             }
          }
       }
       catch (Exception) { ; }
       return str;
    }
    
    0 讨论(0)
  • 2020-11-21 22:58

    Extra information to Firas Assaad answer.

    I have used new StackFrame(1).GetMethod().Name; in .net core 2.1 with dependency injection and I am getting calling method as 'Start'.

    I tried with [System.Runtime.CompilerServices.CallerMemberName] string callerName = "" and it gives me correct calling method

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

    Another approach I have used is to add a parameter to the method in question. For example, instead of void Foo(), use void Foo(string context). Then pass in some unique string that indicates the calling context.

    If you only need the caller/context for development, you can remove the param before shipping.

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