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

时间:2014-07-22 13:09:02

标签: c# reflection

我有以下情况:

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”对象。

我找不到任何为我提供“此”对象的财产。

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

2 个答案:

答案 0 :(得分:0)

我能看到这个工作的唯一方法是,如果你在子类中覆盖它,那么去一帧(在这种情况下,将是孩子的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为止。例如:

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

答案 1 :(得分:-1)

这段代码怎么样??

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

而不是

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