How To Get The Calling Method And Type

0 comments suggest edit

Here are a couple of useful methods for getting information about the caller of a method. The first returns the calling method of the current method. The second returns the type of the caller. Both of these methods require declaring the System.Diagnostics namespace.

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

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

Pop Quiz! Why didn’t I apply the principle of code re-use and implement the second method like so?

public static Type GetCallingType()
{
    return GetCallingMethod().DeclaringType;
}

A virtual cigar and the admiration of your peers to the first person to answer correctly.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

10 responses

  1. Avatar for Aaron Lerch
    Aaron Lerch August 11th, 2006

    Pop Quiz: Because reusing the code in that way would modify the stack and give you the wrong return (it would return whatever type contains the GetCallingType() method).
    In physics this would fall under the Heisenberg Uncertainty Principle where the act of measuring an electron's location actually modifies it's location.

  2. Avatar for jayson knight
    jayson knight August 11th, 2006

    That sounds about right. I struggled with this very thing a while back on a project. The problem with using StackTrace or StackFrame is that IIRC your code has include .pdb files and needs to have debugging enabled (though doesn't necessarily have to be compiled in debug mode).
    I personally like dealing with assembly references better, but it requires more code and is a little more tedious.

  3. Avatar for Ron Grabowski
    Ron Grabowski August 12th, 2006

    I wonder how important it is to mark the methods with this attribute so the compiler doesn't optimize the stack somehow:
    [MethodImpl(MethodImplOptions.NoInlining)]

  4. Avatar for Dimitri Glazkov
    Dimitri Glazkov August 13th, 2006

    I think that's the code I wrote for the logging piece in Subtext, to determine where the logging call was made. Not sure if it's still there...

  5. Avatar for Haacked
    Haacked August 13th, 2006

    Dimitri, I took a look and indeed it is still there! Nice work!

  6. Avatar for dhananjay singh (dhananjay123@
    dhananjay singh (dhananjay123@ August 13th, 2006

    Dear Haacked,
    There is littile typo in your code [It must be typo only ;) I know :) ]
    return type of method GetCallingMethod should be MethodBase insted of MethodInfo.
    happy blogging
    Dhananjay

  7. Avatar for Haacked
    Haacked August 13th, 2006

    Thanks Dhananjay! You're absolutely right, it was just a typo. Funny because I actually compiled and tested the code, and forgot to copy and paste the correct code over. Doh!

  8. Avatar for dhananjay singh (dhananjay123@
    dhananjay singh (dhananjay123@ August 13th, 2006

    and here is the ans.
    If you try to reuse this code, that means you are pusing one more method on the stack, And it will alwys return Type of GetCallingMethod() only.
    codeing is fun
    Dhananjay

  9. Avatar for Marcos
    Marcos August 14th, 2006

    I completely agree with Ron you must use the
    [MethodImpl(MethodImplOptions.NoInlining)]
    Because this is a perfect method to inline and the compile sure choice it has a candite.
    Take into account that you calling method can be inlined too so you are returning the caller to the calling method,that is not what do you want.
    The release mode optimizations can be a really mind cracker :P
    just my 2 cents

  10. Avatar for Haacked
    Haacked August 15th, 2006

    Thanks, that is a good point. These are methods I typically use in debug code, but we do use them in some logging code that could be released in release mode. Good call!