Get run time type of stack frames

邮差的信 提交于 2019-12-19 09:56:28

问题


I was wondering if it were possible to obtain the run time type of method callers in the stack trace.

Consider the following example:

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
{
}

If I create an instance of Child and call Foo

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

Foo will print: Void Foo() (ReflectedType: Parent)

Is there any way to get the actual run time types (Child in this case) of method callers in the stack trace?


回答1:


No. The reason is described by Raymond Chen here.

The relevant quote is:

An object in a block of code can become eligible for collection during execution of a function it called.

It's not intuitive, read the part about JIT and GC working together.

Getting the actual Type requires the instance, but the optimization effort is geared toward making that Garbage, so you can't rely on it still being there.




回答2:


You are calling Parent.Foo(), that's why you are getting Parent type.

One way would be create a method in 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.

But what I can think is the usage. Where do you plan to get that info about stack, types, methods? More likely in some logger. And then you don't really need to know is it Parent.Foo() or Child.Foo(), because you (as programmer) know for sure where Foo() is.

Other thing is what it may be enough (for logger) to only know caller, then it's as simple as

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;
    ...
}


来源:https://stackoverflow.com/questions/23990297/get-run-time-type-of-stack-frames

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!