为什么reflection搜索突然找不到任何东西?

根据这个问题和答案,我有以下代码如何获取ASP.NET C#中请求的文件的MIME类型? 它工作得非常好:

static MimeMappingWrapper() { // dirty trick - Assembly.LoadWIthPartialName has been deprecated //Assembly ass = Assembly.LoadWithPartialName("System.Web"); Assembly ass = Assembly.GetAssembly(typeof (HttpApplication)); Type mimeMappingType = ass.GetType("System.Web.MimeMapping"); GetMimeMappingMethod = mimeMappingType.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic); } 

现在突然mimeMappingType.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic)返回null

可能是什么原因? 在应用程序中没有更改任何特殊内容,即使它是,它如何影响包装类的这个构造函数?

我的猜测是服务器上安装的.NET Framework升级了,新版本下不再出现私有构造函数。

允许程序集开发人员(在本例中为Microsoft)随心所欲地更改任何私有(或内部)类型或成员,而不会将其视为重大更改。

编辑 :我在.NET 4.0下检查了我的PC,该方法仍然存在。 这是它的签名:

 // System.Web.MimeMapping internal static string GetMimeMapping(string FileName) 

在这一点上,我的两个建议是在运行时检查你的实际.NET版本……

 var version = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion(); 

…并枚举MimeMapping类的方法以检查它们是否符合您的期望:

 var methods = mimeMappingType.GetMethods(BindingFlags.Static | BindingFlags.NonPublic); 

更新 :好消息是MimeMapping类及其GetMimeMapping方法似乎可能在.NET 4.5中公开。

但是,这意味着您的代码肯定会中断,因为您只搜索NonPublic方法。 尝试执行全包搜索,看看GetMimeMapping是否显示:

 var methods = mimeMappingType.GetMethods( BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); 

刚碰到这个,可以给出一些额外的背景:

微软会对dll进行半导体升级(例如将MimeMapping从“内部”更改为“公共”)。 计划是这些更改完全进入下一版本的框架。

在.NET 4.0及更高版本中,为了防止开发人员在较新的系统上使用这些修改(可能不知道它会在未修补的计算机上中断),IDE会在“参考assembly”文件夹中使用代码签名的快照(而不是运行时的)来自GAC),主要版本之间没有变化。

这意味着尽管运行时类型是公共的,但您的IDE只能看到内部版本,因​​此如果没有reflection,您仍然无法使用它。

您的代码只需更改以检查Public和NonPublic绑定标志,以满足正在使用的版本。 在框架的下一个版本中,您可能只能使用没有reflection的类型。