获取运行时类型的堆栈帧

我想知道是否有可能在堆栈跟踪中获取运行时类型的方法调用程序。

请考虑以下示例:

class Parent { public void Foo() { var stack = new StackTrace(); foreach (var frame in stack.GetFrames()) { var methodInfo = frame.GetMethod(); Console.WriteLine("{0} (ReflectedType: {1})", methodInfo.ToString(), methodInfo.DeclaringType); } } } class Child : Parent { } 

如果我创建一个Child实例并调用Foo

 var child = new Child(); child.Foo(); 

Foo将打印:Void Foo()(ReflectedType:Parent)

有没有办法在堆栈跟踪中获取方法调用者的实际运行时类型(在本例中为Child)?

不,原因是Raymond Chen 在这里描述的。

相关报价是:

代码块中的对象可以在执行其调用的函数期间符合收集条件。

这不直观,阅读有关JIT和GC协同工作的部分。

获取实际类型需要实例,但优化工作是为了制作垃圾,所以你不能依赖它仍然在那里。

你正在调用Parent.Foo() ,这就是你得到Parent类型的原因。

一种方法是在Child创建一个方法:

 class Parent { } class Child : Parent { public void Foo() { var stack = new StackTrace(); foreach (var frame in stack.GetFrames()) { var methodInfo = frame.GetMethod(); Console.WriteLine("{0} (ReflectedType: {1})", methodInfo.ToString(), methodInfo.DeclaringType); } } } 

certificate 。

但我能想到的是用法。 您打算在哪里获得有关堆栈,类型,方法的信息? 更有可能在一些记录器中。 然后你真的不需要知道它是Parent.Foo()还是Child.Foo() ,因为你(作为程序员)确定Foo()在哪里。

其他的事情就是它可能就足够了(对于记录器来说)只知道调用者,然后它就像它一样简单

 public static void Log(string message, Exception exception = null) { var method = new StackFrame(1).GetMethod(); // get caller name, so that you don't need to specify it, when calling Log() var caller = method.DeclaringType.Name + "." + method.Name; ... }