2

I have the following code in almost every function in my source code.

string methodName = MethodBase.GetCurrentMethod().Name;

My question is

Is it recommended to use the above code to achieve the same considering that reflection is a costly affair?

This is used only for logging purposes.

ckv
  • 10,539
  • 20
  • 100
  • 144
  • possible duplicate of [C# how to get the name of the current method from code](http://stackoverflow.com/questions/2652460/c-sharp-how-to-get-the-name-of-the-current-method-from-code) – Hans Passant Mar 17 '14 at 09:22

3 Answers3

8

No, I wouldn't do this everywhere in your source code.

Firstly, I'd use a dedicated logging package which may have cunning ways of doing a better job, and will certainly be less obtrusive in your source code. There are various options available (log4net, nlog etc). Just how important is the method name anyway? I usually find that if I'm logging with enough context in the message, I don't need to know the exact method name. That's more important for exceptions.

Secondly, if you're using C# 5 you can use CallerMemberNameAttribute to get the compiler to specify the name of the method calling a logging function for you. This is obviously much more sensible than doing it at execution time.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

There's a significant performance hit when using this approach to get the name of the current method, so I wouldn't recommend it.

People often mention the CallerMemberNameAttribute class, but this often doesn't play well with now you'd want to use a logging interface. The reason for this is it's typlically applied as a default parameter, which means it has to go to the right of the non default parameters. A lot of logging API have the format:

Info(string format, params object[] values)

Now, adding a parameter that has the CallerMemberNameAttribute is going to be a problem. You can't put it on the right as the params parameters prohibit this, and you can't put it anywhere else as it won't be eligable to be a default parameter. One option would be to change your logging API to something like this:

Info(string format, object[] values, [CallerMemberName] string memberName = "")

But then you have to explicitly create an array for the values, which tends not to flow as well.

Sean
  • 60,939
  • 11
  • 97
  • 136
1

Out of curiosity i decided to time the GetCurrentMethod calls. Using a Stopwatch i called the GetCurrentMethod in a loop and it looks like there is no caching (linear relationship between call number and time)

var sw = new System.Diagnostics.Stopwatch();
sw.Start();
for (var i = 0; i < numberOfCallsToMake; i++)
{
    var methodName = MethodBase.GetCurrentMethod().Name;
}
sw.Stop();
Console.WriteLine("Calling GetCurrentMethod {0} times: {1} ms",numberOfCallsToMake,  sw.ElapsedMilliseconds);

which gives us

Calling GetCurrentMethod 100 times: 0 ms
Calling GetCurrentMethod 1000 times: 1 ms
Calling GetCurrentMethod 10000 times: 14 ms
Calling GetCurrentMethod 100000 times: 148 ms
Calling GetCurrentMethod 1000000 times: 1335 ms
Calling GetCurrentMethod 10000000 times: 13403 ms
Calling GetCurrentMethod 100000000 times: 134079 ms

It doesn't look like there's any caching of the method name (don't know how that could work) because there's a linear relationship between time and number of calls.

A logging framework may be smarter and store the current method name in order to shave off these milliseconds and you'd receive additional benefits from it too. So follow Jon Skeet's advice and use a logging framework

samy
  • 14,832
  • 2
  • 54
  • 82