How to Get the Calling Method Name and Type Using Reflection

How can I find the method that called the current method?

Try this:

using System.Diagnostics;
// Get call stack
StackTrace stackTrace = new StackTrace();
// Get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);

one-liner:

(new System.Diagnostics.StackTrace()).GetFrame(1).GetMethod().Name

It is from Get Calling Method using Reflection [C#].

How do I get the calling method name and type using reflection?


public class SomeClass
{
public void SomeMethod()
{
StackFrame frame = new StackFrame(1);
var method = frame.GetMethod();
var type = method.DeclaringType;
var name = method.Name;
}
}

Now let's say you have another class like this:

public class Caller
{
public void Call()
{
SomeClass s = new SomeClass();
s.SomeMethod();
}
}

name will be "Call" and type will be "Caller".

UPDATE: Two years later since I'm still getting upvotes on this

In .NET 4.5 there is now a much easier way to do this. You can take advantage of the CallerMemberNameAttribute.

Going with the previous example:

public class SomeClass
{
public void SomeMethod([CallerMemberName]string memberName = "")
{
Console.WriteLine(memberName); // Output will be the name of the calling method
}
}

Retrieving the calling method name from within a method

I don't think it can be done without tracing the stack. However, it's fairly simple to do that:

StackTrace stackTrace = new StackTrace();
MethodBase methodBase = stackTrace.GetFrame(1).GetMethod();
Console.WriteLine(methodBase.Name); // e.g.

However, I think you really have to stop and ask yourself if this is necessary.

How do I find the caller of a method using stacktrace or reflection?


StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace()

According to the Javadocs:

The last element of the array represents the bottom of the stack, which is the least recent method invocation in the sequence.

A StackTraceElement has getClassName(), getFileName(), getLineNumber() and getMethodName().

You will have to experiment to determine which index you want
(probably stackTraceElements[1] or [2]).

How To Get Name of Calling Method and Executing Method of Lambda Expression

The expression given in the lambda being a delegate, you will have to traverse into its content to get the actual method details. I suggest updating the parameter type for the Helper method (MeasureExecution) to be Expression<Func<T>> instead of Func<T> as an Expression type would allow you to easily examine the contents of a Func. I did try a sample with the below snippet and it worked as per the expectation. I used a static variable in place of your LogDetails to make my life easier in double checking what is being sent.

public static T MeasureExecution<T>(Expression<Func<T>> func, MethodBase sourceMethod)
{
T funcResult;

funcResult = func.Compile()();

try
{
var executingMethod = string.Empty;
var methodExpression = func.Body as MethodCallExpression;

if (methodExpression != null)
{
executingMethod = methodExpression.Method != null ? methodExpression.Method.Name : "Cannot find method details";
}

MethodInformation = string.Format("Method Being Executed: {0}, Executing Source Class: {1}, Executing Source Method: {2}", executingMethod, sourceMethod.ReflectedType.Name, sourceMethod.Name);
}
catch { }

return funcResult;
}

public static string MethodInformation { get; private set; }

And this is the output I get -
Method Being Executed: GetData, Executing Source Class: DataBinder, Executing Source Method: FindData

How to get Class name that is calling my method?

You can use StackFrame of System.Diagnostics and MethodBase of System.Reflection.

StackFrame(Int32, Boolean) initializes a new instance of the StackFrame class that corresponds to a frame above the current stack frame, optionally capturing source information.

MethodBase, provides information about methods and constructors.

public static string NameOfCallingClass()
{
string fullName;
Type declaringType;
int skipFrames = 2;
do
{
MethodBase method = new StackFrame(skipFrames, false).GetMethod();
declaringType = method.DeclaringType;
if (declaringType == null)
{
return method.Name;
}
skipFrames++;
fullName = declaringType.FullName;
}
while (declaringType.Module.Name.Equals("mscorlib.dll", StringComparison.OrdinalIgnoreCase));

return fullName;
}

Your logger classes call this method:

public static void Error()
{
string name = NameOfCallingClass();
}

Getting the caller method name - Reflection and CallerInfo attribute

You have to reset timer before second loop. sw.Start starts Stopwatch from state it was after first loop, so second result is actually time for both StackTrace and Attribute-based solutions summed together.

CallerMethodName is compile-type feature, it should definitely be faster.

With fixed code timing for CallerMethodName from your results is:

21.7074064 - (9.48074760000001 * 2) = 2.7459111999999806

That's much faster, isn't it?

subtracted first time twice: once for lack of Reset call and once for += instead of =.

Update

These results seems to be much too big. Are you sure you're using Release build, run from outside Visual Studio? I think not, because otherwise you'd get exact same results for both: callerName is never used and will probably be optimized to no-op (at least for second case).

How to get the calling method properties in c#

In MorpheeException constructior you can find calling method using reflection and then use it.

How to use reflection to call method by name

Something along the lines of:

MethodInfo method = service.GetType().GetMethod(serviceAction);
object result = method.Invoke(service, new object[] { request });
return (R) result;

You may well want to add checks at each level though, to make sure the method in question is actually valid, that it has the right parameter types, and that it's got the right return type. This should be enough to get you started though.



Related Topics



Leave a reply



Submit