获取对象调用层次结构
本文关键字:层次结构 调用 取对象 获取 | 更新日期: 2023-09-27 18:01:18
假设我有三个类:
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
轻松获得),调用a.do_A()的对象b的对象的引用,以及调用b. do_b ()的对象c的对象的引用。
我认为这应该是可能的,因为我可以通过调用堆栈获得调用层次结构,所以我确信我应该能够获得关于调用方法的对象的更多信息。
首先,您所描述的是一种糟糕的编程实践。方法的行为应该取决于它的参数,而不是谁调用它。一个方法应该是可靠的,这样你就知道无论谁调用它,你都会得到相同的行为。
第二,你似乎普遍错误地认为调用堆栈是一个真实的东西,告诉你调用来自。这根本不是调用堆栈的目的,尽管对于调试场景它确实很有用。调用堆栈的目的是告诉你下一个要去哪里,而不是告诉你从来的地方。现在,通常情况下,你下一步要去的地方也是你来自哪里。根据知道下一步要去的地方,你可以推断出你从哪里来,这一事实通常是有用的,但你不能依赖它。调用堆栈只允许包含足够的信息来确定下一步要去哪里;它可以扔掉所有不需要的信息来决定你下一步要去哪里。第三,你似乎有一个普遍但错误的信念,认为调用堆栈是决定你下一步要去哪里的唯一系统,因此,你从哪里来。事实并非如此。正如我们将在下一个版本的c#和VB中看到的那样,异步控制流完全分离了"你从哪里来"answers"你接下来要去哪里",并且根本不使用调用堆栈。
也许你可以告诉我们为什么你想要这个信息。也许有更好的方法来做你想做的事情
一般来说,你所要求的在。net中是不可能的——即使在理论上也是如此。也许不太直观,即使对象上的实例方法正在执行中,也不能保证对象仍然是活的。从本质上讲,CLR足够智能,可以识别传递给实例方法的隐藏我的意思是我想要得到. do_a()中的object()可以很容易地由此获得的),指的对象b调用a.do_A()调用对象c的引用b.do_B () .
我认为这应该是可能的,因为我可以得到调用层次调用堆栈,所以我想我应该能得到更多的信息关于调用的对象方法。
this
引用何时不再被解引用。当这种情况发生时,被引用的对象就有资格进行收集(当然,假设不能通过其他根访问它)。作为推论,当所调用的方法仍在执行时,"调用对象"完全有可能是死的。在您的具体示例中,完全有可能b
和c
(实际上是由这些变量引用的对象)不再存在,而 A.do_A()
正在执行。
我推荐阅读Raymond Chen的文章:什么时候一个对象可以用于垃圾收集?为了更好地理解这个问题:
对象可以符合的执行期间收集方法。
如果你觉得这与你的问题无关,考虑一下那篇文章的倒数第二段:
另一个顾客问:"有没有获取实例引用的方法的每一帧都被调用栈?静态方法除外课程)。"另一位顾客问道大致相同的问题,但在a不同的语境:"我想要我的方法沿着堆栈往上走,如果它调用者是OtherClass。哦,我想获取OtherClass的this对象。喷火这样我就可以查询其他属性了从它。"你现在知道了你自己回答这些问题。
这是不可能的,如果A
想知道谁调用了do_A
,那么do_A
必须定义一个参数object caller
,并且它的调用者负责将正确的对象实例传递给参数