Graeme Hill's Dev Blog

.NET reflection: don't rely on the call stack, it's a trap!

Star date: 2011.299

In recent memory I have twice tried to write reflection code that seemed totally badass at the time but turned out to be just plain bad. One case involved the use of GetCallingAssembly() and the other involved navigating the stack trace with stackTrace.GetFrame(1). While there is nothing inherently wrong with these functions (ie: they can be used perfectly fine for logging or debugging) you absolutely cannot depend on a specific result due to runtime optimizations by the .NET JIT compiler. For example, imagine A calls B and B calls C. If C runs GetCallingAssembly() then you would expect to get the assembly of B; however, if function B gets inlined in A (which is not uncommon) then technically A is directly calling C, and you will actually get A as a result! In fact, if you check the MSDN documentation they even warn you about this:

If the method that calls the GetCallingAssembly method is expanded inline by the just-in-time (JIT) compiler, or if its caller is expanded inline, the assembly that is returned by GetCallingAssembly may differ unexpectedly.

The documentation for GetExecutingAssembly() has no such warning, but just to be safe I prefer to be explicit with something like this: myObject.GetType().Assembly

comments powered by Disqus