GetCallingAssembly()和GetExecutingAssembly()是否同样倾向于JIT内联?

sha*_*oth 8 .net c# reflection jit

Assembly.GetExecutingAssembly()Assembly.GetCallingAssembly().请注意,GetCallingAssembly()具有一个Remark提的是,根据JIT内联的行为方式可以是可能的是,一个方法是(或不是)内联到另一个,因此GetCallingAssembly()返回不同的结果.

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

为什么GetExecutingAssembly()描述中没有提到JIT inining类似于GetCallingAssembly()描述的说法?

Joã*_*elo 13

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

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

这可以通过实验以及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
Run Code Online (Sandbox Code Playgroud)

原因GetCallingAssembly很容易,因为您正在寻找调用者的调用者,并且局部变量仅保证调用者不是内联的,这意味着可以内联祖父素方法导致意外结果.