c#反射-在堆栈跟踪中找到第一个不是该对象构造函数一部分的方法

本文关键字:对象 构造函数 方法 一部分 第一个 反射 堆栈 跟踪 | 更新日期: 2023-09-27 18:13:54

我试图使用反射来找到对象正在构造的位置("new A()"在代码中发生的位置),并将其存储以供调试。这是一个框架,许多类将从基类继承,具有不同的继承深度,所以我不能只沿着堆栈跟踪一个常量。

class A
{
     public string Origin {get; private set;}
     public A()
     {
     Origin = // reflection goes here
     }
}
class B : A
{
     public B()
     {
     }
}
class C : A
{
     B b = new B()
}
class X
{
     void M()
     {
         var b=new B()
         var c=new C()
         /* desired values:
         b.Origin = "X.M"
         c.Origin = "X.M"
         c.B.Origin = "C..ctor"
         */
    }
}

到目前为止,我有:

var stacktrace = new StackTrace()
var i = 0;
while(stacktrace.GetFrame(i).GetMethod().IsConstructor)
{
    i++
}
var method = stacktrace.GetFrame(i).GetMethod();
Origin = method.DeclaringType.FullName + "." + method.Name;

这个可以工作,除了c.b.l origin——因为B是在C的构造函数中构造的,所以它仍然返回X.M

还有其他建议吗?

c#反射-在堆栈跟踪中找到第一个不是该对象构造函数一部分的方法

这是我想到的最好的——它可能会与边缘情况混淆(如果类C的构造函数创建了另一个C类型的对象——或者从C派生的类型)——但它处理了我需要的一切

var stackTrace = new StackTrace();
var i = 0;
var myType = GetType();
while (stackTrace.GetFrame(i).GetMethod().IsConstructor 
       && stackTrace.GetFrame(i).GetMethod().DeclaringType.IsAssignableFrom(myType))
{
    i++;
}
var methodCallingTheConstructor = stackTrace.GetFrame(i).GetMethod();