【问题标题】:Assembly.GetTypes - why use this if GetExportedTypes is available?Assembly.GetTypes - 如果 GetExportedTypes 可用,为什么要使用它?
【发布时间】:2011-10-10 11:41:25
【问题描述】:

我不知道你会使用哪种场景。

如果您有一个包含一些公共和私有(或内部)类型的程序集,那么只有公共类型应该从外部可用。任何内部的或私有的类型都不应该可用,事实上,它们的存在不应该是可发现的。

因此,GetTypesGetExportedTypes - 在我看来,应该返回相同的东西。

显然我在想这个错误 - 每个是什么?

谢谢!

【问题讨论】:

  • 反射还提供对不可访问类型的访问。
  • 还没有超级解决!但我接受了最接近的那个。

标签: c# .net-assembly


【解决方案1】:

来自MSDN docs

Assembly.GetTypes 方法
返回值类型:System.Type[]
包含在此程序集中定义的所有类型的数组。

来自MSDN docs

Assembly.GetExportedTypes 方法
返回值
类型:System.Type[]
表示在此程序集中定义的类型在程序集外可见的数组。

所以GetTypes() 调用确实会为您提供在程序集中定义的所有 类型——无论它们对您是否“可见”和可实例化。可能看起来很奇怪 - 但如果您想检查自己、您自己的程序集(或与您的代码在同一名称空间中的程序集)怎么办?如果需要,您需要能够看到所有内容。

【讨论】:

  • 好的,谢谢,但我对 WHY 更感兴趣,也就是说,从客户的角度来看 - 如果我构建并发布一个程序集,则只有公共接口应该是可发现的。也就是说,您检查自己的程序集是对的。
【解决方案2】:

语言级别的可见性与反射级别的类型可见性无关。

反射的整个想法是您可以看到所有类型、成员等并检查它们;说用于代码生成目的或其他。同样,您也有诸如使用InternalsVisibleToAttribute 的场景,以及正如其他人所说的,当您需要反映您自己的程序集时。这些都是完全合法的,如果不可用,将无法实现(从而严重限制 .Net 框架)。

因此,默认应该返回所有类型 - 只有在运行时尝试使用类型时,才会看到它。也可以绕开; .Net 框架本身依赖于一些能够实例化其他程序集自己的私​​有类型的场景;您也可以跳过对自己动态构建的程序集的可见性检查。我在为我们的内部应用程序编写的自定义滚动 IOC 和 DI 框架上使用此功能,以允许我们的开发人员将类型完全隐藏在外部代码之外,但仍可在他们的应用程序中使用。

【讨论】:

    【解决方案3】:

    对于确实会出现这种情况的外部程序集,但是如果您在自己的程序集上调用 GetTypes 会怎样?

    然后你也会看到私有的和内部的,这是合乎逻辑的。

    【讨论】:

      【解决方案4】:

      GetExportedTypes() 不包括受保护/私有类型。 GetTypes() 包括所有类型。

      关于internal 类型,GetExportedTypes() 的 MSDN 文档不清楚。

      【讨论】:

        【解决方案5】:

        如果您想要所有公共类型,您可以使用 GetExportedTypes,但如果您还想要所有其他类型,您可以使用 GetTypes。即使类型是私有的或内部的,您也可以创建新实例并通过反射和动态使用它,所以我认为这两者都不是多余的。

        【讨论】:

          【解决方案6】:

          我正在调查遇到此问题的 Web API bug,并发现 Assembly.GetExportedTypes 和“Assembly.GetTypes”之间的一个非常重要的区别。它在文档中,但不是很清楚。

          Assembly.GetExportedTypes 如果无法加载任何依赖程序集,则会引发“FileNotFoundException”。 'Assembly.GetTypesthrowsReflectionTypeLoadExceptionwhich contains types that are loaded successfully. So, if you want to succeed even if some of the types in the assembly cannot be loaded, you should useGetTypesand notGetExportedTypes`。

          因为Assembly.GetExportedTypes 不会抛出ReflectionTypeLoadException,所以这段代码不起作用。

                  Type[] types;
                  try
                  {
                      types = assembly.GetExportedTypes();
                  }
                  catch (ReflectionTypeLoadException e)
                  {
                      types = e.Types;
                  }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-09-06
            • 2021-01-14
            • 1970-01-01
            • 2012-08-03
            相关资源
            最近更新 更多