Retrieving the calling method name from within a method [duplicate]

試著忘記壹切 提交于 2019-11-26 05:54:37

问题


Possible Duplicate:
How can I find the method that called the current method?

I have a method in an object that is called from a number of places within the object. Is there a quick and easy way to get the name of the method that called this popular method.

Pseudo Code EXAMPLE:

public Main()
{
     PopularMethod();
}

public ButtonClick(object sender, EventArgs e)
{
     PopularMethod();
}

public Button2Click(object sender, EventArgs e)
{
     PopularMethod();
}

public void PopularMethod()
{
     //Get calling method name
}

Within PopularMethod() I would like to see the value of Main if it was called from Main ... I\'d like to see \"ButtonClick\" if PopularMethod() was called from ButtonClick

I was looking at the System.Reflection.MethodBase.GetCurrentMethod() but that won\'t get me the calling method. I\'ve looked at the StackTrace class but I really didn\'t relish running an entire stack trace every time that method is called.


回答1:


I don't think it can be done without tracing the stack. However, it's fairly simple to do that:

StackTrace stackTrace = new StackTrace();
MethodBase methodBase = stackTrace.GetFrame(1).GetMethod();
Console.WriteLine(methodBase.Name); // e.g.

However, I think you really have to stop and ask yourself if this is necessary.




回答2:


In .NET 4.5 / C# 5, this is simple:

public void PopularMethod([CallerMemberName] string caller = null)
{
     // look at caller
}

The compiler adds the caller's name automatically; so:

void Foo() {
    PopularMethod();
}

will pass in "Foo".




回答3:


This is actually really simple.

public void PopularMethod()
{
    var currentMethod = System.Reflection.MethodInfo
        .GetCurrentMethod(); // as MethodBase
}

But be careful through, I'm a bit skeptical to if inlining the method has any effect. You can do this to make sure that the JIT compiler won't get in the way.

[System.Runtime.CompilerServices.MethodImpl(
 System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public void PopularMethod()
{
    var currentMethod = System.Reflection.MethodInfo
        .GetCurrentMethod();
}

To get the calling method:

[System.Runtime.CompilerServices.MethodImpl(
 System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public void PopularMethod()
{
    // 1 == skip frames, false = no file info
    var callingMethod = new System.Diagnostics.StackTrace(1, false)
         .GetFrame(0).GetMethod();
}



回答4:


Just pass in a parameter

public void PopularMethod(object sender)
{

}

IMO: If it's good enough for events it should be good enough for this.




回答5:


I have often found my self wanting to do this, but have always ending up refactoring the design of my system so I don't get this "Tail wagging the dog" anti-pattern. The result has always been a more robust architecture.




回答6:


While you can most definitley trace the Stack and figure it out that way, I would urge you to rethink your design. If your method needs to know about some sort of "state", I would say just create an enum or something, and take that as a Parameter to your PopularMethod(). Something along those lines. Based on what you're posting, tracing the stack would be overkill IMO.




回答7:


I think you do need to use the StackTrace class and then StackFrame.GetMethod() on the next frame.

This seems like a strange thing to use Reflection for though. If you are defining PopularMethod, can't go define a parameter or something to pass the information you really want. (Or put in on a base class or something...)



来源:https://stackoverflow.com/questions/615940/retrieving-the-calling-method-name-from-within-a-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!