【问题标题】:How do I get the calling method name and type using reflection? [duplicate]如何使用反射获取调用方法名称和类型? [复制]
【发布时间】:2011-03-06 23:00:57
【问题描述】:

可能重复:
How can I find the method that called the current method?

我想写一个方法来获取调用方法的名称,以及包含调用方法的类的名称。

是否可以使用 C# 反射?

【问题讨论】:

标签: c# reflection


【解决方案1】:
public class SomeClass
{
    public void SomeMethod()
    {
        StackFrame frame = new StackFrame(1);
        var method = frame.GetMethod();
        var type = method.DeclaringType;
        var name = method.Name;
    }
}

现在假设你有另一个这样的类:

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

name 将是“Call”,type 将是“Caller”。

更新:两年后,我仍然对此表示赞同

在 .NET 4.5 中,现在有一种更简单的方法来执行此操作。您可以利用CallerMemberNameAttribute。

继续前面的例子:

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

【讨论】:

  • 这是一个尽可能好的解决方案,但您需要记住,除非您禁用 JIT 方法内联,否则这不一定会返回您在发布版本中期望的答案。
  • 在.NET 3.5的解决方案中,应该在SomeMethod上面加上[MethodImpl(MethodImplOptions.NoInlining)]来避免内联。将 false 传递给构造函数还可以防止从 PDB 文件中加载文件名/行数据,从而加快 StackTrace 的构建。
  • +1 用于更新答案
  • 值得注意的是,使用[CallerMemberName] 解决方案,编译器会处理整个事情,因此它对性能更好,因为在运行时没有实际反射。
  • 可惜没有[CallerTypeName] 来获取调用方法的声明类型...
【解决方案2】:

您可以通过StackTrace 使用它,然后您可以从中获取反射类型。

StackTrace stackTrace = new StackTrace();           // get call stack
StackFrame[] stackFrames = stackTrace.GetFrames();  // get method calls (frames)

StackFrame callingFrame = stackFrames[1];
MethodInfo method = callingFrame.GetMethod();
Console.Write(method.Name);
Console.Write(method.DeclaringType.Name);
【解决方案3】:

这实际上是可以使用当前堆栈跟踪数据和反射的组合来完成的。

public void MyMethod()
{
     StackTrace stackTrace = new System.Diagnostics.StackTrace();
     StackFrame frame = stackTrace.GetFrames()[1];
     MethodInfo method = frame.GetMethod();
     string methodName = method.Name;
     Type methodsClass = method.DeclaringType;
}

StackFrame 数组上的1 索引将为您提供名为MyMethod 的方法

【讨论】:

    【解决方案4】:

    是的,原则上这是可能的,但它不是免费的。

    你需要创建一个StackTrace,然后你可以查看调用堆栈的StackFrame's。

    【讨论】:

      【解决方案5】:

      从技术上讲,您可以使用 StackTrace,但这非常慢,并且在很多时候不会给您期望的答案。这是因为在发布构建期间可能会发生优化,这将删除某些方法调用。因此,您无法确定发布时 stacktrace 是否“正确”。

      真的,在 C# 中没有任何万无一失或快速的方法。您真的应该问自己为什么需要它以及如何构建您的应用程序,这样您就可以在不知道调用它的方法的情况下做您想做的事情。

      【讨论】:

      • 这是 A. 调试版本,B. 调用其他程序集。通过 System.Diagnostics.Process 启动其他程序所需的时间使使用 StackFrame 类所产生的任何事情都相形见绌。
      • 我这样做是为了自动配置测试套件。
      猜你喜欢
      • 1970-01-01
      • 2012-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多