通过反射获取顶部派生类型的名称

本文关键字:类型 派生 顶部 反射 获取 | 更新日期: 2023-09-27 18:14:01

我有以下场景:

public class Program
{
    static void Main(string[] args)
    {
        new Child().Foo(); //will display "Parent" but I want it to display "Child"
    }
}
class Parent
{
    virtual void Foo()
    {
        var firstFrame = new StackTrace().GetFrames().First();
        var method = firstFrame.GetMethod();
        Console.WriteLine(method.DeclaringType.Fullname);
    }
}
class Child : Parent
{
}

正如您所看到的,我希望控制台显示"Child"而不是"Parent"。或者换一种方式,我想沿着堆栈跟踪,对于堆栈跟踪的每个方法,我都想获得"this"对象。

我找不到任何为我提供"this"对象的属性。

我实际上想列出一个装饰器模式的所有链元素

通过反射获取顶部派生类型的名称

我能看到这个工作的唯一方法是如果你在子类中重写它,然后向上走一帧(在这种情况下,将是孩子的foo)。

public class Program
{
    static void Main(string[] args)
    {
        new Child().Foo(); //will display "Child"
    }
}
class Parent
{
    public virtual void Foo()
    {
        StackFrame frame = new StackFrame(1);
        var method = frame.GetMethod();
        Console.WriteLine(method.DeclaringType.FullName);
    }
}
class Child : Parent
{
    public override void Foo()
    {
        base.Foo();
    }
}

如果你想让它成为一个列表,你可以把堆栈帧部分放在一个循环中,直到你用完foo's。如:

class Parent
{
    public virtual void Foo()
    {
        StackTrace trace = new StackTrace();
        List<StackFrame> frames = new List<StackFrame>(trace.GetFrames());
        var thisMethod = frames[0].GetMethod().Name;
        //we don't want ourselves in the list
        frames.RemoveAt(0);
        foreach (var frame in frames)
        {
            var method = frame.GetMethod();
            //we only want foo's
            if (method.Name == thisMethod)
            {
                Console.WriteLine(method.ReflectedType.FullName);
            }
            else
            {
                // when we've run out, we can get out
                break;
            }
        }
    }
}

这段代码怎么样?

Console.WriteLine(this.GetType().FullName);

而不是

var firstFrame = new StackTrace().GetFrames().First();
var method = firstFrame.GetMethod();
Console.WriteLine(method.DeclaringType.FullName);