如何获取包含调用当前方法的方法的类的名称?

Tro*_*zza 21 c#

我有一个要求,我需要知道类的名称(ApiController),它有一个方法(GetMethod),由另一个类(OtherClass)的另一个方法(OtherMethod)调用.

为了帮助解释这一点,我希望下面的伪代码片段有所帮助.

ApiController.cs

public class ApiController
{
    public void GetMethod()
    {
        OtherMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

OtherClass.cs

public class OtherClass()
{
    public void OtherMethod()
    {
        Console.WriteLine(/*I want to get the value 'ApiController' to print out*/)
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试过的:

  • 我看过如何找到调用当前方法的方法?答案将获得调用方法(OtherMethod),但不是具有该方法的类(ApiController)
  • 我尝试[CallerMemberName]并使用StackTrace属性,但这些没有得到方法的类名

Ric*_*imo 22

using System.Diagnostics;

var className = new StackFrame(1).GetMethod().DeclaringType.Name;
Run Code Online (Sandbox Code Playgroud)

转到堆栈的上一级,找到方法,并从方法中获取类型.这可以避免您需要创建一个昂贵的完整StackTrace.

FullName如果需要完全限定的类名,可以使用.

编辑:边缘案例(突出以下评论中提出的问题)

  1. 如果启用了编译优化,则可能会内联调用方法,因此您可能无法获得所期望的值.(来源:Johnbot)
  2. async方法被编译成状态机,所以再次,你可能得不到你期望的.(图片来源:Phil K)

  • 这不是100%可靠.如果启用了优化,那么"GetMethod"可能会被内联并且不会显示在堆栈跟踪中. (6认同)
  • 这在`async`方法中不起作用. (4认同)

ken*_*yzx 12

所以可以这样做,

new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().DeclaringType.Name
Run Code Online (Sandbox Code Playgroud)

StackFrame表示调用堆栈上的方法,索引1为您提供包含当前执行方法的直接调用方的帧,ApiController.GetMethod()在此示例中.

现在你有了框架,然后MethodInfo通过调用检索那个框架StackFrame.GetMethod(),然后使用它的DeclaringType属性MethodInfo来获取定义方法的类型,即ApiController.

  • 为了避免任何混淆,你的行中的`GetMethod()`与OP的`ApiController.GetMethod()`无关,对吧? (2认同)

er-*_*sho 5

您可以通过以下代码实现此目的

首先,您需要添加命名空间 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

实例stackTrace取决于您的实施环境.您可以在本地或全球定义它

要么

您可以使用以下方法而无需创建StackTrace实例

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

试试这可能对你有帮助