如何使用反射获取调用方法名称和类型?

Bil*_*eal 155 c# reflection

可能重复:
如何找到调用当前方法的方法?

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

有可能用C#反射吗?

BFr*_*ree 415

public class SomeClass
{
    public void SomeMethod()
    {
        StackFrame frame = new StackFrame(1);
        var method = frame.GetMethod();
        var type = method.DeclaringType;
        var name = method.Name;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在让我们说你有另一个这样的类:

public class Caller
{
   public void Call()
   {
      SomeClass s = new SomeClass();
      s.SomeMethod();
   }
}
Run Code Online (Sandbox Code Playgroud)

名称将为"呼叫",类型将为"呼叫者"

更新两年后,我仍然对此有所了解

在.Net 4.5中,现在有一种更简单的方法可以做到这一点.你可以利用CallerMemberNameAttribute

继上一个例子:

public class SomeClass
{
    public void SomeMethod([CallerMemberName]string memberName = "")
    {
        Console.WriteLine(memberName); //output will be name of calling method
    }
}
Run Code Online (Sandbox Code Playgroud)

  • +1用于更新答案 (40认同)
  • 太糟糕了,没有`[CallerTypeName]`来获取调用方法的声明类型...... (18认同)
  • 值得注意的是,使用`[CallerMemberName]`解决方案,编译器会处理整个事情,因此在性能上更好,因为在运行时没有实际的反射. (10认同)
  • 这是一个很好的解决方案,但您需要记住,除非您禁用JIT方法内联,否则这不一定会返回您在发布版本中所期望的答案. (9认同)
  • 在.NET 3.5解决方案中,您应该在SomeMethod上面添加[MethodImpl(MethodImplOptions.NoInlining)]以避免内联.将false传递给构造函数还可以防止从PDB文件加载文件名/行数据,从而加快StackTrace的构建. (7认同)
  • 警告:如果您使用此答案中的STACKFRAME建议,则必须注意从DEBUG vs RELEASE模式运行时代码可能会产生不同的结果.我不推荐它,因为追踪它是一场噩梦.如果您仍然决定使用它,那么我建议您阅读此博客文章中的信息:https://corengen.wordpress.com/2011/09/14/different-number-of-stack-frames-between-debug-和释放,建立/ (5认同)
  • 性能表现不好吗? (3认同)

Are*_*ren 21

您可以使用它来使用它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);
Run Code Online (Sandbox Code Playgroud)


ckr*_*mer 11

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

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

1上索引StackFrame数组会给你这调用的方法MyMethod


Luc*_*ero 7

是的,在原则上它是可能的,但它不是免费的.

您需要创建一个StackTrace,然后您可以查看调用堆栈的StackFrame.


Bis*_*hnu 7

从技术上讲,你可以使用StackTrace,但这很慢,并且不会给你很多时候所期望的答案.这是因为在发布版本中,可能会发生删除某些方法调用的优化.因此,您无法确定在发布时堆栈跟踪是否"正确".

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