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.这个局部变量具有防止方法调用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
Run Code Online (Sandbox Code Playgroud)
原因GetCallingAssembly很容易,因为您正在寻找调用者的调用者,并且局部变量仅保证调用者不是内联的,这意味着可以内联祖父素方法导致意外结果.