如何找到调用当前方法的方法?

时间:2023-02-09 10:07:36

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 I want to go one step beneath this in the stack trace. I've considered parsing the stack trace, but I am hoping to find a cleaner more explicit way, something like Assembly.GetCallingAssembly() but for methods.

在登录c#时,如何知道调用当前方法的方法的名称?我对System.Reflection.MethodBase.GetCurrentMethod()非常了解,但是我想在堆栈跟踪中进一步了解它。我已经考虑过解析堆栈跟踪,但是我希望找到一种更清晰、更明确的方法,比如Assembly.GetCallingAssembly(),而是方法。

18 个解决方案

#1


380  

Try this:

试试这个:

using System.Diagnostics;
// Get call stack
StackTrace stackTrace = new StackTrace();

// Get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);

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

它来自于使用反射的Get调用方法[c#]。

#2


251  

In C# 5 you can get that information using caller info:

在c# 5中,您可以使用呼叫者信息获得该信息:

//using System.Runtime.CompilerServices;
public void SendError(string Message, [CallerMemberName] string callerName = "") 
{ 
    Console.WriteLine(callerName + "called me."); 
} 

You can also get the [CallerFilePath] and [CallerLineNumber].

您还可以获得[CallerFilePath]和[CallerLineNumber]。

#3


79  

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.

虽然StackTrace在上面运行得非常快,并且在大多数情况下不会出现性能问题,但是调用者的信息仍然要快得多。在一个1000次迭代的示例中,我将它的速度缩短了40倍。

#4


57  

In general, you can use the System.Diagnostics.StackTrace class to get a System.Diagnostics.StackFrame, and then use the GetMethod() method to get a System.Reflection.MethodBase object. However, there are some caveats to this approach:

通常,您可以使用System.Diagnostics软件。StackTrace类以获取System.Diagnostics。StackFrame,然后使用GetMethod()方法获取System.Reflection。MethodBase对象。然而,对这种方法有一些注意事项:

  1. It represents the runtime stack -- optimizations could inline a method, and you will not see that method in the stack trace.
  2. 它表示运行时堆栈——优化可以内联一个方法,您在堆栈跟踪中看不到这个方法。
  3. It will not show any native frames, so if there's even a chance your method is being called by a native method, this will not work, and there is in-fact no currently available way to do it.
  4. 它不会显示任何本机框架,因此,如果您的方法有被本机方法调用的机会,这将不起作用,而且实际上目前没有可用的方法来实现它。

(NOTE: I am just expanding on the answer provided by Firas Assad.)

(注:我只是在扩大菲拉斯·阿萨德提供的答案。)

#5


53  

We can improve on Mr Assad's code (the current accepted answer) just a little bit by instantiating only the frame we actually need rather than the entire stack:

我们只需实例化我们实际需要的框架,而不是整个堆栈,就可以稍微改进阿萨德的代码(当前被接受的答案):

new StackFrame(1).GetMethod().Name;

This might perform a little better, though in all likelihood it still has to use the full stack to create that single frame. Also, it still has the same caveats that Alex Lyman pointed out (optimizer/native code might corrupt the results). Finally, you might want to check to be sure that new StackFrame(1) or .GetFrame(1) don't return null, as unlikely as that possibility might seem.

这可能会表现得更好一些,尽管很有可能它仍然需要使用整个堆栈来创建那个单独的帧。此外,它仍然有Alex Lyman指出的同样的注意事项(优化器/本机代码可能会破坏结果)。最后,您可能想要检查,以确保新的StackFrame(1)或. getframe(1)不会返回null,尽管这种可能性似乎不大。

See this related question: Can you use reflection to find the name of the currently executing method?

请参见这个相关的问题:是否可以使用反射来查找当前正在执行的方法的名称?

#6


50  

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

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.

可见,使用属性要快得多!实际上快了25倍。

#7


13  

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.

考虑面向方面的编程(AOP),比如PostSharp,它不需要从代码中调用,而是修改代码,从而知道它在任何时候的位置。

#8


13  

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

在。net 4.5中,您可以使用调用者信息属性:

  • 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. 微软——来电信息(c#)
  3. Microsoft - CallerFilePathAttribute Class
  4. 微软——CallerFilePathAttribute类
  5. Microsoft - CallerLineNumberAttribute Class
  6. 微软——CallerLineNumberAttribute类
  7. Microsoft - CallerMemberNameAttribute Class
  8. 微软——CallerMemberNameAttribute类

#9


8  

/// <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;
}

#10


7  

Obviously this is a late answer, but I have a better option if you can use .NET 4.5 or more:

显然这是一个迟来的答案,但我有一个更好的选择,如果你可以使用。net 4.5或更多:

internal static void WriteInformation<T>(string text, [CallerMemberName]string method = "")
{
    Console.WriteLine(DateTime.Now.ToString() + " => " + typeof(T).FullName + "." + method + ": " + text);
}

This will print the current Date and Time, followed by "Namespace.ClassName.MethodName" and ending with ": text".
Sample output:

这将打印当前日期和时间,然后是“Namespace.ClassName”。方法学名称,以“:文本”结尾。样例输出:

6/17/2016 12:41:49 PM => WpfApplication.MainWindow..ctor: MainWindow initialized

Sample use:

示例使用:

Logger.WriteInformation<MainWindow>("MainWindow initialized");

#11


6  

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

#12


4  

private static MethodBase GetCallingMethod()
{
  return new StackFrame(2, false).GetMethod();
}

private static Type GetCallingType()
{
  return new StackFrame(2, false).GetMethod().DeclaringType;
}

A fantastic class is here: http://www.csharp411.com/c-get-calling-method/

这里有一个很棒的课程:http://www.csharp411.com/c-get-calling-method/

#13


2  

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.

我使用的另一种方法是向该方法添加一个参数。例如,使用void Foo(string context)代替void Foo()。然后传入一些惟一的字符串,该字符串指示调用上下文。

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

如果您只需要调用者/上下文进行开发,您可以在发送之前删除param。

#14


1  

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

查看。net中的日志记录方法名。注意不要在产品代码中使用它。StackFrame可能不可靠……

#15


1  

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

我们也可以使用lambda来查找调用者。

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):

1。更改方法签名,我们有一个类型动作的参数(Func也可以):

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.

2。Lambda名称不是随机生成的。规则似乎是:> __X,其中CallerMethodName被前面的函数替换,X是一个索引。

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:

3所示。调用MethodA时,动作/Func参数必须由调用方方法生成。例子:

MethodA(() => {});

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

4所示。在MethodA中,我们现在可以调用上面定义的helper函数,并找到调用方方法的方法。

Example:

例子:

MethodInfo callingMethodInfo = GetCallingMethodInfo(serverCall.Method.Name);

#16


0  

StackFrame caller = (new System.Diagnostics.StackTrace()).GetFrame(1);
string methodName = caller.GetMethod().Name;

will be enough, I think.

我想这就够了。

#17


0  

Calling it this way, allows you to pull previous methods, even if that method belongs to another application.

这样打电话,让你把以前的方法,即使该方法属于另一个应用程序。

    private enum METHOD_HISTORY
    {
        LAST_METHOD = 1,
        PREVIOUS_METHOD = 2
    }   //METHOD_HISTORY


    [MethodImpl(MethodImplOptions.NoInlining)]
    private string GetMethodName(METHOD_HISTORY lastMethod = METHOD_HISTORY.LAST_METHOD )
    {
        string retVal = "";

        StackTrace st = new StackTrace(new StackFrame((int)lastMethod));
        retVal = String.Format("{0}.{1}", st.GetFrame(0).GetMethod().ReflectedType.FullName, st.GetFrame(0).GetMethod().Name);

        return retVal;
    }

Calling it:

叫它:

string currentMethod = GetMethodName();

or

string prevtMethod = GetMethodName(METHOD_HISTORY.PREVIOUS_METHOD)

#18


-1  

var callingMethod = new StackFrame(1, true).GetMethod();
string source = callingMethod.ReflectedType.FullName + ": " + callingMethod.Name;

#1


380  

Try this:

试试这个:

using System.Diagnostics;
// Get call stack
StackTrace stackTrace = new StackTrace();

// Get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);

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

它来自于使用反射的Get调用方法[c#]。

#2


251  

In C# 5 you can get that information using caller info:

在c# 5中,您可以使用呼叫者信息获得该信息:

//using System.Runtime.CompilerServices;
public void SendError(string Message, [CallerMemberName] string callerName = "") 
{ 
    Console.WriteLine(callerName + "called me."); 
} 

You can also get the [CallerFilePath] and [CallerLineNumber].

您还可以获得[CallerFilePath]和[CallerLineNumber]。

#3


79  

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.

虽然StackTrace在上面运行得非常快,并且在大多数情况下不会出现性能问题,但是调用者的信息仍然要快得多。在一个1000次迭代的示例中,我将它的速度缩短了40倍。

#4


57  

In general, you can use the System.Diagnostics.StackTrace class to get a System.Diagnostics.StackFrame, and then use the GetMethod() method to get a System.Reflection.MethodBase object. However, there are some caveats to this approach:

通常,您可以使用System.Diagnostics软件。StackTrace类以获取System.Diagnostics。StackFrame,然后使用GetMethod()方法获取System.Reflection。MethodBase对象。然而,对这种方法有一些注意事项:

  1. It represents the runtime stack -- optimizations could inline a method, and you will not see that method in the stack trace.
  2. 它表示运行时堆栈——优化可以内联一个方法,您在堆栈跟踪中看不到这个方法。
  3. It will not show any native frames, so if there's even a chance your method is being called by a native method, this will not work, and there is in-fact no currently available way to do it.
  4. 它不会显示任何本机框架,因此,如果您的方法有被本机方法调用的机会,这将不起作用,而且实际上目前没有可用的方法来实现它。

(NOTE: I am just expanding on the answer provided by Firas Assad.)

(注:我只是在扩大菲拉斯·阿萨德提供的答案。)

#5


53  

We can improve on Mr Assad's code (the current accepted answer) just a little bit by instantiating only the frame we actually need rather than the entire stack:

我们只需实例化我们实际需要的框架,而不是整个堆栈,就可以稍微改进阿萨德的代码(当前被接受的答案):

new StackFrame(1).GetMethod().Name;

This might perform a little better, though in all likelihood it still has to use the full stack to create that single frame. Also, it still has the same caveats that Alex Lyman pointed out (optimizer/native code might corrupt the results). Finally, you might want to check to be sure that new StackFrame(1) or .GetFrame(1) don't return null, as unlikely as that possibility might seem.

这可能会表现得更好一些,尽管很有可能它仍然需要使用整个堆栈来创建那个单独的帧。此外,它仍然有Alex Lyman指出的同样的注意事项(优化器/本机代码可能会破坏结果)。最后,您可能想要检查,以确保新的StackFrame(1)或. getframe(1)不会返回null,尽管这种可能性似乎不大。

See this related question: Can you use reflection to find the name of the currently executing method?

请参见这个相关的问题:是否可以使用反射来查找当前正在执行的方法的名称?

#6


50  

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

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.

可见,使用属性要快得多!实际上快了25倍。

#7


13  

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.

考虑面向方面的编程(AOP),比如PostSharp,它不需要从代码中调用,而是修改代码,从而知道它在任何时候的位置。

#8


13  

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

在。net 4.5中,您可以使用调用者信息属性:

  • 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. 微软——来电信息(c#)
  3. Microsoft - CallerFilePathAttribute Class
  4. 微软——CallerFilePathAttribute类
  5. Microsoft - CallerLineNumberAttribute Class
  6. 微软——CallerLineNumberAttribute类
  7. Microsoft - CallerMemberNameAttribute Class
  8. 微软——CallerMemberNameAttribute类

#9


8  

/// <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;
}

#10


7  

Obviously this is a late answer, but I have a better option if you can use .NET 4.5 or more:

显然这是一个迟来的答案,但我有一个更好的选择,如果你可以使用。net 4.5或更多:

internal static void WriteInformation<T>(string text, [CallerMemberName]string method = "")
{
    Console.WriteLine(DateTime.Now.ToString() + " => " + typeof(T).FullName + "." + method + ": " + text);
}

This will print the current Date and Time, followed by "Namespace.ClassName.MethodName" and ending with ": text".
Sample output:

这将打印当前日期和时间,然后是“Namespace.ClassName”。方法学名称,以“:文本”结尾。样例输出:

6/17/2016 12:41:49 PM => WpfApplication.MainWindow..ctor: MainWindow initialized

Sample use:

示例使用:

Logger.WriteInformation<MainWindow>("MainWindow initialized");

#11


6  

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

#12


4  

private static MethodBase GetCallingMethod()
{
  return new StackFrame(2, false).GetMethod();
}

private static Type GetCallingType()
{
  return new StackFrame(2, false).GetMethod().DeclaringType;
}

A fantastic class is here: http://www.csharp411.com/c-get-calling-method/

这里有一个很棒的课程:http://www.csharp411.com/c-get-calling-method/

#13


2  

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.

我使用的另一种方法是向该方法添加一个参数。例如,使用void Foo(string context)代替void Foo()。然后传入一些惟一的字符串,该字符串指示调用上下文。

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

如果您只需要调用者/上下文进行开发,您可以在发送之前删除param。

#14


1  

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

查看。net中的日志记录方法名。注意不要在产品代码中使用它。StackFrame可能不可靠……

#15


1  

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

我们也可以使用lambda来查找调用者。

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):

1。更改方法签名,我们有一个类型动作的参数(Func也可以):

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.

2。Lambda名称不是随机生成的。规则似乎是:> __X,其中CallerMethodName被前面的函数替换,X是一个索引。

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:

3所示。调用MethodA时,动作/Func参数必须由调用方方法生成。例子:

MethodA(() => {});

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

4所示。在MethodA中,我们现在可以调用上面定义的helper函数,并找到调用方方法的方法。

Example:

例子:

MethodInfo callingMethodInfo = GetCallingMethodInfo(serverCall.Method.Name);

#16


0  

StackFrame caller = (new System.Diagnostics.StackTrace()).GetFrame(1);
string methodName = caller.GetMethod().Name;

will be enough, I think.

我想这就够了。

#17


0  

Calling it this way, allows you to pull previous methods, even if that method belongs to another application.

这样打电话,让你把以前的方法,即使该方法属于另一个应用程序。

    private enum METHOD_HISTORY
    {
        LAST_METHOD = 1,
        PREVIOUS_METHOD = 2
    }   //METHOD_HISTORY


    [MethodImpl(MethodImplOptions.NoInlining)]
    private string GetMethodName(METHOD_HISTORY lastMethod = METHOD_HISTORY.LAST_METHOD )
    {
        string retVal = "";

        StackTrace st = new StackTrace(new StackFrame((int)lastMethod));
        retVal = String.Format("{0}.{1}", st.GetFrame(0).GetMethod().ReflectedType.FullName, st.GetFrame(0).GetMethod().Name);

        return retVal;
    }

Calling it:

叫它:

string currentMethod = GetMethodName();

or

string prevtMethod = GetMethodName(METHOD_HISTORY.PREVIOUS_METHOD)

#18


-1  

var callingMethod = new StackFrame(1, true).GetMethod();
string source = callingMethod.ReflectedType.FullName + ": " + callingMethod.Name;