【问题标题】:Why would Reflection search suddenly not find anything?为什么反射搜索会突然找不到任何东西?
【发布时间】:2012-02-27 00:34:33
【问题描述】:

根据这个问题&回答How do I get the MIME type of a file being requested in ASP.NET C#?,我有以下代码 它工作得很好:

    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

可能是什么原因?应用程序没有什么特别的改变,即使改变了,它如何影响包装类的构造函数?

【问题讨论】:

  • 嗯,可能有些地方发生了变化,如果它在工作之前和现在都没有。

标签: c# reflection mime-types


【解决方案1】:

我的猜测是安装在服务器上的 .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);

【讨论】:

  • 它与我的本地工作站有关,因为我刚刚尝试过,它可以在 Web 服务器上运行
  • 尝试执行上面的两个sn-ps,告诉我们version的结果是什么,以及methods中返回的方法名称。
  • 我接受这个答案,因为这是唯一合乎逻辑的解释,我的工作站的 .NET Framework 一定发生了一些事情,它不再工作了。
  • 嗯,运行时版本是4.0.30319,返回的方法只有一个,它是{Void SetIntegratedApplicationContext(IntPtr)}
  • 使用扩展的绑定标志列表时,GetMethods() 调用确实找到了方法
【解决方案2】:

我自己也遇到过这个问题,可以提供一些额外的背景信息:

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

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

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

您的代码只需更改以检查 Public 和 NonPublic 绑定标志,以适应碰巧正在使用的版本。在框架的下一个版本中,您可能只能够使用该类型而无需反射。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-06
    • 2012-09-11
    • 2021-03-26
    • 1970-01-01
    • 2020-07-24
    • 2012-12-30
    • 2014-07-03
    • 1970-01-01
    相关资源
    最近更新 更多