views:

3153

answers:

7

Like the title says: Can reflection give you the name of the currently executing method.

I'm inclined to guess not, because of the Heisenberg problem. How do you call a method that will tell you the current method without changing what the current method is? But I'm hoping someone can prove me wrong there.

Update:

  • Part 2: Could this be used to look inside code for a property as well?
  • Part 3: What would the performance be like?

Final Result
I learned about MethodBase.GetCurrentMethod(). I also learned that not only can I create a stack trace, I can create only the exact frame I need if I want.

To use this inside a property, just take a .Substring(4) to remove the 'set_' or 'get_'.

+1  A: 

I think you should be able to get that from creating a StackTrace. Or, as @edg and @Lars Mæhlum mention, MethodBase.GetCurrentMethod()

bdukes
+1  A: 

Yes definately.

I actually do this in this function I use in my code framework to get the calling method:

 public static T CreateWrapper<T>(Exception innerException, params object[] parameterValues) where T : Exception, new()
 {
  if (parameterValues == null)
  {
   parameterValues = new object[0];
  }

  Exception exception = null;
  StringBuilder builder = new StringBuilder();
  MethodBase method = new StackFrame(2).GetMethod();
  ParameterInfo[] parameters = method.GetParameters();
  builder.AppendFormat(CultureInfo.InvariantCulture, ExceptionFormat, new object[] { method.DeclaringType.Name, method.Name });
  if ((parameters.Length > 0) || (parameterValues.Length > 0))
  {
   builder.Append(GetParameterList(parameters, parameterValues));
  }

  exception = (Exception)Activator.CreateInstance(typeof(T), new object[] { builder.ToString(), innerException });
  return (T)exception;
 }

Basically what's happening here is; I walk the stack here to find the calling method and then get the parameters of that method before tying them to the values passed to it. This allows me to easily create error reportd for my functions. All you need to do is get the current stack frame instead of the calling one.

As others have said for the current methods name you can also use:

MethodBase.GetCurrentMethod()

I prefer walking the stack because if look internally at that method it simply creates a StackCrawlMark anyway. Addressing the Stack directly seems clearer to me

Lex
+30  A: 

System.Reflection.MethodBase.GetCurrentMethod().Name;

Ed Guiness
+9  A: 

Try this inside the Main method in an empty console program:

MethodBase method = MethodBase.GetCurrentMethod();
Console.WriteLine(method.Name);

Console Output:
Main

Lars Mæhlum
exactly what I needed. thanks.
scottmarlowe
+2  A: 

EDIT: MethodBase is probably a better way to just get the method you're in (as opposed to the whole calling stack). I'd still be concerned about inlining however.

You can use a StackTrace within the method:

StackTrace st = new StackTrace(true);

And the look at the frames:

// The first frame will be the method you want (However, see caution below)
st.GetFrames();

However, be aware that if the method is inlined, you will not be inside the method you think you are. You can use an attribute to prevent inlining:

[MethodImpl(MethodImplOptions.NoInlining)]
dpp
+10  A: 

The snippet provided by Lex was a little long, so I'm pointing out the important part since no one else used the exact same technique:

string MethodName = new StackFrame(0).GetMethod().Name;

This should return identical results to the MethodBase.GetCurrentMethod().Name technique, but it's still worth pointing out because I could implement this once in its own method using index 1 for the previous method and call it from a number of different properties. Also, it only returns one frame rather then the entire stack trace:

private string GetPropertyName()
{  //.SubString(4) strips the property prefix (get|set) from the name
    return new StackFrame(1).GetMethod().Name.Substring(4);
}

It's a one-liner, too ;)

Joel Coehoorn
+1  A: 

How about this this:

StackFrame frame = new StackFrame(1);
frame.GetMethod().Name; //Gets the current method name

MethodBase method = frame.GetMethod();
method.DeclaringType.Name //Gets the current class name
jesal