Tech Off Thread

12 posts

Getting current method name in C# similar to __FUNCTION__ in C

Back to Forum: Tech Off
  • BitFlipper

    Is it possible to get the current method name in C# similar like you can get the current function name in C/C++ using __FUNCTION__?

    I tried to do this once with reflection but I couldn't figure out how to do it.

  • BitFlipper

    OK looks like StackFrame will do what I need. Just wondering how slow it will be since I want to use it for logging purposes. Something like:

    public void Foo()
    {
        StartMethod(new StackFrame());
        ...
        ...
    }

    StartMethod will then log whatever is passed in as the stack frame.

  • blowdart

    , BitFlipper wrote

    OK looks like StackFrame will do what I need. Just wondering how slow it will be since I want to use it for logging purposes. Something like:

    1
    2
    3
    4
    5
    6
    public void Foo()
    {
        StartMethod(new StackFrame());
        ...
        ...
    }

    StartMethod will then log whatever is passed in as the stack frame.

    It's not speedy. Heck it's more expensive that throwing exceptions.I'd suggest passing the name in as a string and hoping people use it right.

    If you must go this route you don't have to pass it in at all though. Just to this in the logger.

    StackTrace stackTrace = new StackTrace();
    MethodBase methodBase = stackTrace.GetFrame(1).GetMethod();
  • felix9

    CallerMemberName ?

  • cheong

    Slow, but useful if you've wrap it in #if DEBUG ... #endif directive. (DEBUG is automatically defined when building with DEBUG configuration. Can be changed in "Build" tab of Project Properties, via "Define DEBUG constant" checkbox in corresponding build configuration.)

    So when you compile without DEBUG, this won't eat away your performance.

    Recent Achievement unlocked: Code Avenger Tier 4/6: You see dead program. A lot!
    Last modified
  • lucianoc

    @BitFlipper: New in C# 5.0  (Caller Information) http://msdn.microsoft.com/en-us/library/hh534540.aspx

     

    public void DoProcessing()
    {
        TraceMessage("Something happened.");
    }

    public void TraceMessage(string message,
            [CallerMemberName] string memberName = "",
            [CallerFilePath] string sourceFilePath = "",
            [CallerLineNumber] int sourceLineNumber = 0)
    {
        Trace.WriteLine("message: " + message);
        Trace.WriteLine("member name: " + memberName);
        Trace.WriteLine("source file path: " + sourceFilePath);
        Trace.WriteLine("source line number: " + sourceLineNumber);
    }

  • wkempf

    The reflection route won't always work, due to inlining. The CallerMemberNameAttribute is more reliable, but it doesn't give you the current method, but rather the calling method. Should still work for what you're trying to do, obviously, but you specifically asked about getting the current method name. I'd also point out that the CallerMemberName approach can be misused, though that's probably not something you're worried about.

  • BitFlipper

    Actually, it turns out StackFrame isn't that slow, less than 1 ms. And since I can't use C# 5.0, I'll stick with that for now.

    But it is good to know this feature was added to 5.0.

    BTW this is all my own code so I have full control over what happens where. However I need this because hand-coding each method is going to take a long time, vs simply copy/pasting the same thing everywhere.

  • evildictait​or

    , BitFlipper wrote

    vs simply copy/pasting the same thing everywhere.

    Whoa There!

    If copy and pasting is the answer, it's probably time to write a function and call that instead.

  • ScanIAm

    OK, I'm possibly missing something here, but wouldn't:

    string method = 
    string.Format("{0}.{1}", MethodBase.GetCurrentMethod().DeclaringType.FullName, MethodBase.GetCurrentMethod().Name);

     

    Work?

  • BitFlipper

    @ScanIAm: Yes that is exactly what I was looking for. I guess I just missed that, thanks! A much better solution for sure.

  • Ion Todirel

    @BitFlipper: If you have a logger, you shouldn't expose this glue outside the logger, make it transparent. So you need the caller not the current function name.

    void Foo() {
        this.Log("something happened")
    }

    void Log(string message) {
        LogInternal(string.Format("[timestamp] callerName message", ...));
    }

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.