How to reliably determine the calling assembly in .NET 4.0
在.NET 3.5及更低版本中,以下(略为粗糙的示例)效果很好:
装配A:
1 2 3 4 5 6 7 | public static class ClassInAssemblyA { public static string GetCallingAssemblyLocation() { return System.Reflection.Assembly.GetCallingAssembly().GetName(false).CodeBase; } } |
装配B:
1 2 3 4 5 6 7 8 9 | public class ClassInAssemblyB { public string AssemblyName { get; private set; } public ClassInAssemblyB() { AssemblyName = ClassInAssemblyA.GetCallingAssemblyLocation(); } } |
程序集C:
1 2 | var assemblyName = new ClassInAssemblyB().AssemblyName; Assert.That(assemblyName.Contains("AssemblyB")); |
不幸的是,.NET 4.0 CLR似乎已经过优化,可以将AssemblyA代码内联到AssemblyB中,因此,上述测试在Debug模式下执行时实际上通过了,但在Release模式下失败了。逐步执行时,基本上不可能重现该错误。
一种停止内联的方法是要求调用者每次引用AssemblyA时都添加属性
是否有其他方法可以在运行时确定调用程序集的文件名是什么?
除了使用
我的理解是,除非您尝试测试自递归调用,否则JIT编译器将始终尊重
这是基于
http://bytes.com/topic/c-sharp/answers/509557-race-conditions-c-eventing
(据我所读,它没有讨论尾递归)