I have a requirement where I need to know the name of the class (ApiController) which has a method (GetMethod) which is called by another m
So it can be done like this,
new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().DeclaringType.Name
StackFrame represents a method on the call stack, the index 1 gives you the frame that contains the immediate caller of the currently executed method, which is ApiController.GetMethod()
in this example.
Now you have the frame, then you retrieve the MethodInfo
of that frame by calling StackFrame.GetMethod()
, and then you use the DeclaringType
property of the MethodInfo
to get the type in which the method is defined, which is ApiController
.
Why not simply pass the name as constructor parameter? This doesn't hide the dependency, unlike StackFrame
/StackTrace
.
For example:
public class ApiController
{
private readonly OtherClass _otherClass = new OtherClass(nameof(ApiController));
public void GetMethod()
{
_otherClass.OtherMethod();
}
}
public class OtherClass
{
private readonly string _controllerName;
public OtherClass(string controllerName)
{
_controllerName = controllerName;
}
public void OtherMethod()
{
Console.WriteLine(_controllerName);
}
}
using System.Diagnostics;
var className = new StackFrame(1).GetMethod().DeclaringType.Name;
Goes to the previous level of the Stack, finds the method, and gets the type from the method. This avoids you needing to create a full StackTrace, which is expensive.
You could use FullName
if you want the fully qualified class name.
Edit: fringe cases (to highlight the issues raised in comments below)
async
methods get compiled into a state machine, so again, you may not get what you expect. (Credit: Phil K)You can achieve this by below code
First you need to add namespace using System.Diagnostics;
public class OtherClass
{
public void OtherMethod()
{
StackTrace stackTrace = new StackTrace();
string callerClassName = stackTrace.GetFrame(1).GetMethod().DeclaringType.Name;
string callerClassNameWithNamespace = stackTrace.GetFrame(1).GetMethod().DeclaringType.FullName;
Console.WriteLine("This is the only name of your class:" + callerClassName);
Console.WriteLine("This is the only name of your class with its namespace:" + callerClassNameWithNamespace);
}
}
The instance of stackTrace
is depend upon your implementation environment. you may defined it locally or globally
OR
You may use below method without creating StackTrace
instance
public class OtherClass
{
public void OtherMethod()
{
string callerClassName = new StackFrame(1).GetMethod().DeclaringType.Name;
string callerClassNameWithNamespace = new StackFrame(1).GetMethod().DeclaringType.FullName;
Console.WriteLine("This is the only name of your class:" + callerClassName);
Console.WriteLine("This is the only name of your class with its namespace:" + callerClassNameWithNamespace);
}
}
Try this may it help you