2

一个方法可以被内联;有一个属性可以防止这种情况(“有一个属性”)。但是,由于 JITter 的尾调用优化(http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx),显然一个方法也可能无法在 x64 上获得自己的堆栈帧。这会影响 的行为MethodBase.GetCurrentMethod吗?

我能找到的讨论主要是关于内联的(什么时候有资格被 CLR 内联的方法?)。虽然这些讨论本身很有趣,但我的问题实际上是关于在什么情况下——如果有的话——MethodBase.GetCurrentMethod可以依赖于识别程序员发出调用的相同方法(例如,后期绑定到一个方法当前方法实际上是替代方法)。内联是一种MethodBase.GetCurrentMethod可能被愚弄的方式,但我想知道它是否是唯一的方式?

4

1 回答 1

2

否 - 方法要么在运行时内联,要么不内联。

我相信,如果有人要实现自己的运行时,它可能会被愚弄 -MethodBase.GetCurrentMethod最终归结为这一点,声明在RuntimeMethodHandle

[SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern IRuntimeMethodInfo 
  _GetCurrentMethod(ref StackCrawlMark stackMark);

在自定义运行时中,它可以做任何事情——而且在未来它也可以做任何事情。目前,我认为 Microsoft 运行时不会返回正确方法的唯一方法是内联代码;例如,不能为 Mono 说话。然而,始终如此,我认为,就像依靠始终存在的内部类型的反射私有字段来使一段代码能够工作一样。

在我尝试过的几乎所有情况下(我现在不再担心)或有人试图证明需要能够可靠地识别调用方法,在分析之外,内联方法的问题总是会出现。

然而,现实是,担心这些方法有多重要?

如果可靠性绝对至关重要,那么您将获得更多运气使用 IL-rewriter 后编译来注入日志调用;这可能是方法感知的,因此可以颠覆内联,即使它发生(如果重写的 IL 变得足够大,可能不会,从而损害性能)。或者,如果您不喜欢自己滚动,则可能需要一个 AOP 库 - 例如PostSharp

于 2012-01-17T22:58:23.100 回答