【问题标题】:Get run time type of stack frames获取堆栈帧的运行时类型
【发布时间】:2014-07-22 07:42:03
【问题描述】:

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

考虑以下示例:

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)

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

【问题讨论】:

  • 你的例子没有多大用处。你还有其他例子吗?在您的示例中,对于第一种方法Foo,您可以通过this.GetType() 获得原始类型?
  • @SriramSakthivel 我正在寻找一种适用于堆栈跟踪中每一帧的通用方法

标签: c# .net stack-trace callstack


【解决方案1】:

没有。原因由 Raymond Chen here 描述。

相关引用是:

代码块中的对象可以在其调用的函数执行期间有资格被收集。

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

获取实际的 Type 需要实例,但优化工作是针对制造该垃圾的,因此您不能依赖它仍然存在。

【讨论】:

  • 谢谢。我问的原因是因为我正在使用提供堆栈跟踪的自定义构建问题报告工具,但是架构非常繁重,并且有很多来自基本类型的方法调用,如果能够扩展它真的很方便以某种方式获取运行时类型的工具。哦,好吧:)
  • +1 多么棒的文章。雷蒙德再次交付。
【解决方案2】:

你打电话给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);
        }
    }
}

Proof.

但我能想到的是用法。您打算从哪里获得有关堆栈、类型、方法的信息?在某些记录器中更有可能。然后你真的不需要知道是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;
    ...
}

【讨论】:

  • 这是试图回滚问题。但是 OPs 的想法是足够有效的。
  • 也许我的例子有误导性。我正在寻求一个通用解决方案,该解决方案将从堆栈跟踪中的 any 帧获取运行时类型。将方法移动到子类并不能真正解决我的问题,而且在大多数情况下都会损害 OO 设计。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-12
  • 1970-01-01
  • 1970-01-01
  • 2015-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多