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

时间:2018-07-31 05:33:49

标签: c#

我有一个要求,我需要知道类的名称( ApiController ),该类具有一个方法( GetMethod ),该方法由另一个方法( > OtherMethod )来自其他类( OtherClass )。

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

ApiController.cs

public class ApiController
{
    public void GetMethod()
    {
        OtherMethod();
    }
}

OtherClass.cs

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

我尝试过的事情:

  • 我查看了How can I find the method that called the current method?,答案将为我提供了调用方法( OtherMethod ),但没有调用该方法的类( ApiController
  • 我尝试了[CallerMemberName]并使用了StackTrace属性,但是这些并没有为我提供方法的类名

4 个答案:

答案 0 :(得分:22)

using System.Diagnostics;

var className = new StackFrame(1).GetMethod().DeclaringType.Name;

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

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

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

  1. 如果启用了编译优化,则可能会内联调用方法,因此您可能无法获得期望的值。 (信用:Johnbot
  2. async方法被编译到状态机中,因此,同样,您可能无法获得期望的结果。 (信用:Phil K

答案 1 :(得分:12)

所以可以这样,

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

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

现在有了框架,然后通过调用MethodInfo来检索框架的StackFrame.GetMethod(),然后使用DeclaringType的{​​{1}}属性来获得定义方法的类型,即MethodInfo

答案 2 :(得分: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);
    }
}

stackTrace的实例取决于您的实现环境。您可以在本地或全局定义

OR

您可以在不创建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);
    }
}

尝试一下可能对您有帮助

答案 3 :(得分:3)

为什么不简单地将名称作为构造函数参数传递呢?与StackFrame / StackTrace不同,这不会隐藏依赖性。

例如:

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);
    }
}
相关问题