这可能是重复的,但我还没有看到这个确切的问题或类似的问题,其询问/回答的日期比 .Net 4 的发布日期更新。
我正在寻找一个临时的 hack,它允许我查看调用堆栈并获取堆栈中的所有调用对象(不是方法,而是保存方法的实例)。最终我需要他们的哈希码。
这可能吗?
编辑:
无论它是否出现在我的问题中,真的是在问是否有一种简单/内置的方法来做到这一点。真的,这只是一个权宜之计,直到我可以对系统的其他部分进行重大更改。谢谢你的好答案。看到他们之后,我想我会等。 . . :)
最佳答案
你想在这里实现什么?
看看我一个月前回答的类似问题: How to get current value of EIP in managed code? 。你可能会从中得到一些启发。或者你可能认为它太丑了(后者+1)。
如果您想做的只是在程序 session 中组合“唯一”调用路径,请继续:我肯定会使用 AOP 编织器和线程本地存储。这样不会太难。
警告 1:哈希对通用 .NET 对象不是很有用
一个随机对象的哈希码可能会随着它在堆上的位置而变化。供引用:在 MONO 上,在禁用移动堆分配器的情况下,Object::GetHash 是这个漂亮的代码块 (mono/metadata/monitor.c)
#else
/*
* Wang's address-based hash function:
* http://www.concentric.net/~Ttwang/tech/addrhash.htm
*/
return (GPOINTER_TO_UINT (obj) >> MONO_OBJECT_ALIGNMENT_SHIFT) * 2654435761u;
#endif
当然,对于移动分配器来说,在对象的整个生命周期内保证一个恒定的散列会稍微复杂一些,但你明白了:每个运行时都会生成不同的散列,完成的分配量将改变 future 的默认散列码相同的对象。
警告 2:您的堆栈将包含外星框架
即使您通过提供适当的确定性哈希函数修复了该部分,您也需要每个堆栈帧都是“可识别”类型。情况可能并非如此。如果您使用类似于 LINQ、匿名类型、静态构造函数、委托(delegate)的任何东西,当然不会;各种各样的事情可能是将堆栈帧与(匿名)助手类型的堆栈帧交错,甚至是 JIT 编译器发明的性能蹦床以优化尾递归、大型切换跳转表或在多个重载之间共享代码。
要点:堆栈分析很难:如果您要进行它,您绝对应该使用正确的 API。
结论:
一定要有一个球。但听从建议
关于c# - 获取调用对象的哈希码?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6103034/