开发者

How can I know which method call my method?

I've 3 methods A(开发者_Go百科), B() and C(), both A() and B() call C(). In method C(), how can I know it call from A() or B()?


You shouldn't need to. Some method should perform a specific task, which is influenced by its parameters and the object attributes, not the caller.


I don't recommend this approach - other posters point out better ways of handling this. But if you really, really need to know who called you, without changing C()'s parameters, you can do this:

static void A()
{
    C();
}

static void C()
{
    StackTrace st = new StackTrace();
    Console.WriteLine(st.GetFrame(1).GetMethod().Name); // prints "A"
}

Note that generating a StackTrace is somewhat costly. Not a big deal, though, unless you're doing it in code that you're calling very frequently.

Again, you almost certainly find a better way of doing whatever you're trying to do.


Method C() should not need to know which method called it. If this is how you are handling your flow logic, you need to think again about how you are writing your code. If we assume that there is some valid reason for needing to know which method called C(), I would create two 'wrapper' methods: C_From_A() and C_From_B(). Any logic specific to the calling methods should be moved to the new methods, while common code is left in the C() method and called from both the new methods:

public void C()
{
   // Common Code goes here
}

public void C_From_A()
{
    // Code only to be called from A() goes here.

    C();  // Common code executed
}

public void C_From_B()
{
    // Code only to be called from B() goes here.

    C();  // Common code executed
}


public void A()
{
    // Other code goes here

    C_From_A();
}

If you need to know for debugging, simple use the debugger to step through your code.


You should to take a look into System.Diagnostics.StackFrame class. An example here: http://www.csharp-examples.net/reflection-callstack/


The easy (and clean) way would be to introduce a new parameter to C and let A and B tell C who called it.


Just set a breakpoint in C()


I agree in principle you shouldn't need to know in most situations.

However the one use case where this may be useful to know is when debugging where certain information came from, In the case of a bad parameter passed.

However in that case its probably better to throw an exception, log the exception and "recover" from it. Obviously this depends on how often the method is called as there is always some overhead with creating an exception. If you need to do this for some other reason than I would suggest you look at your design first.

If you need callbacks I would suggest that you make A and B both implement an interface and pass A or B as a parameter. The interface could have a method called callback and C could call A or B.


In the case where you're trying to figure out where a "bad parameter was passed" you only need to set a conditional breakpoint in that method or have VS break on the exception that would be thrown and then you can examine the call stack (Debug Menu, Window, Call Stack) to see the entire chain of callers (with arguments passed) to this method.


MethodBase callerMethod = new System.Diagnostics.StackFrame(1).GetMethod();

Useful if you're writing an audit / log framework, but really, YDNTN applies here. Plus it's costing a fortune at runtime.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜