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
Wpf Webbrowser Control - How to Suppress Script Errors
Writing Large Number of Records (Bulk Insert) to Access in .Net/C#
New Keyword in Method Signature
How to Read and Modify Ntfs Alternate Data Streams Using .Net
How to Decode a Url Parameter Using C#
Optimal Linq Query to Get a Random Sub Collection - Shuffle
Changing the User Agent of the Webbrowser Control
Why Can't I Have Abstract Static Methods in C#
System.Text.JSON.JSONelement Toobject Workaround
How to Check the Number of Bytes Consumed by a Structure
Searching for a Specific Jtoken by Name in a Jobject Hierarchy
Parsing Large JSON File in .Net
Headless Browser for C# (.Net)
Shouldserialize*() VS *Specified Conditional Serialization Pattern