10

Assembly.GetExecutingAssembly()Assembly.GetCallingAssembly()。请注意,根据 JIT 内联的行为方式,可能有一种方法被(或没有)内联到另一种方法中,因此GetCallingAssembly()返回不同的结果。RemarkGetCallingAssembly()

现在有什么GetExecutingAssembly()不同?JIT 内联在技术上可以内联调用的代码,GetExecutingAssembly()因此该代码现在属于不同的程序集,并且取决于是否发生这种情况GetExecutingAssembly()也可以产生不同的结果。

为什么GetExecutingAssembly()描述中没有与描述类似的提及JIT inning 的GetCallingAssembly()注释?

4

1 回答 1

16

GetExecutingAssembly方法不易受到 JIT 内联的影响,因为同样的原因MethodBase.GetCurrentMethod也不易受到影响,因为它们以类似的方式实现。

两种方法都声明了一个特殊枚举的局部变量StackCrawlMark并将其初始化为StackCrawlMark.LookForMyCaller. GetExecutingAssembly这个局部变量具有防止方法调用或被内联的副作用,GetCurrentMethod这将保证正确的结果。

这得到了实验的支持,也得到了 SSCLI20 中与此枚举相关的评论的支持:

// declaring a local var of this enum type and passing it by ref 
// into a function that needs to do a stack crawl will both prevent inlining of 
// the calle and pass an ESP point to stack crawl to
//
// Declaring these in EH clauses is illegal; 
// they must declared in the main method body

容易受到影响的原因GetCallingAssembly是因为您正在寻找调用者的调用者,而局部变量只保证调用者没有被内联,这意味着祖父方法可能被内联导致意外结果。

于 2012-10-01T08:39:43.890 回答