C# 获取对象调用层次结构

C# 获取对象调用层次结构,c#,function,object,methods,stack-trace,C#,Function,Object,Methods,Stack Trace,假设我有3门课: class A { void do_A() { //Check object call hierarchy } } class B { void do_B() { A a; a.do_A(); } } class C { void do_C() { B b; b.do_A(); } } 然后我打电话: C c; c.do_C(); 如何从A的do_A()中获取对象调用层次结

假设我有3门课:

class A {
   void do_A() {
      //Check object call hierarchy
    }
}
class B {
   void do_B() {
      A a;
      a.do_A();
    }
}
class C {
   void do_C() {
      B b;
      b.do_A();
    }
}
然后我打电话:

C c;
c.do_C();
如何从A的do_A()中获取对象调用层次结构

我的意思是我想得到a.do_a()中对象的引用(通过
this
可以很容易地得到),对象b的引用称为a.do_a(),对象c的引用称为b.do_b()


我认为这应该是可能的,因为我可以通过调用堆栈获得调用层次结构,因此我确信我应该能够获得有关调用方法的对象的更多信息。

如果
A
想要了解调用
do\u A
的对象,这是不可能的,然后,
do_A
必须定义一个参数
对象调用方
,调用方负责将正确的对象实例传递给该参数

我的意思是我想得到 a.do_a()中的对象(可以轻松 由此获得),参考 调用a.do_a()的对象b 调用的对象c的引用 b、 做某事

我认为这应该是可能的, 因为我可以得到调用层次结构 使用调用堆栈,所以我相信我应该 能够得到更多的信息 关于调用 方法

一般来说,你所要求的在.NET中是不可能的——即使在理论上也是如此。也许不直观地说,即使对象上的实例方法正在执行中,也不能保证该对象仍然是活动的。从本质上讲,CLR足够智能,能够识别传递给实例方法的隐藏
引用何时不再被解引用。当发生这种情况时,引用的对象就有资格被收集(当然,假设它不能通过其他根访问)

作为推论,“调用对象”也完全有可能在其调用的方法仍在执行时死亡。在您的特定示例中,
b
c
(实际上是这些变量所指的对象)在执行
A.do_A()
时,很可能不再存在

当然,这意味着您所寻找的信息在过程中可能不再以任何形式可用,并且任何“神奇”API都不应该能够可靠地生成它

我建议阅读陈雷蒙的文章:为了更好地理解这个问题:

对象可以成为符合条件的对象 在执行 方法在该对象上

如果你觉得这与你的问题无关,那么考虑文章中的第二个段落:

另一位客户问:“有没有 获取实例引用的方法 正在为中的每个帧调用 堆栈?(静态方法除外,共 ”另一位顾客问道 大致相同的问题,但在一个 不同的语境:“我想要我的方法 向上走,如果 打电话的人是另一类人。福,我想 为OtherClass.Foo获取此对象的 所以我可以查询其他属性 你现在知道的足够多了 自己回答这些问题


首先,您描述的是一种糟糕的编程实践。方法的行为应该取决于它的参数,而不是谁调用它。一个方法应该是可靠的,这样你就知道无论谁调用它,你都会得到同样的行为

其次,您似乎普遍错误地认为调用堆栈是真实的,告诉您调用来自哪里。这根本不是调用堆栈的目的,不过对于调试场景来说,它确实很有用。调用堆栈的目的是告诉您下一步要去哪里,而不是告诉您从哪里来。现在,通常情况下,你下一步要去的地方也是你的来源地。事实上,通常你可以通过知道你下一步要去哪里来推断你来自哪里,这通常是有用的,但你不能依赖它。调用堆栈只允许包含足够的信息来确定下一步要去哪里;它可以扔掉你下一步要去哪里所不需要的每一点信息

第三,您似乎普遍但错误地认为,调用堆栈是决定下一步走向的唯一系统,因此,您来自哪里。事实并非如此。正如我们将在下一版本的C#和VB中看到的,异步控制流完全脱离了“你从哪里来”和“你下一步要去哪里”,根本不使用调用堆栈


也许你可以告诉我们你为什么想要这些信息。可能有更好的方法来做你想做的事。

你说的获得参考是什么意思?您的方法无效,因此不会返回任何内容。通过读取stackTrace和stackFrames,您还需要什么?不幸的是,这是不可能的。您可以获取方法,但不能获取实例。您可以获取每个StackFrame的对象类型,但这不会提供对它的引用。(好吧,至少我在文档中找不到它)@dlev-很容易获得静态信息(类型、方法名等),但我正在寻找调用它的实际对象的运行时引用。有什么具体原因使我无法从程序的堆栈跟踪和实际堆栈中获得这些信息吗?“此”信息可能存储在我们使用的每个对象的某个位置。当我们从方法返回到对象的范围时,它就会被检索到。老实说,我能找到的最好的理由是它没有多大意义,如果你需要它,那么可能有另一种方法来设计系统,不需要这种黑客。好的,但直到它不能保证它被释放,那为什么我不能得到这些信息呢?“this”信息应该仍然存储在某个地方,这样当我从该方法返回时,它就可以被使用。如果