Assembly.GetTypes - 如果有GetExportedTypes为什么要使用它?

10
我对在哪种情况下使用其中一种方法感到困惑。
如果您有一个包含一些公共和私有(或内部)类型的程序集,那么只有公共类型应该在外部可用。任何内部或私有的类型都不应该可用,实际上它们的存在也不应被发现。
因此,在我看来,GetTypesGetExportedTypes应该返回相同的结果。
显然,我的想法是错误的——每个方法的作用是什么?
谢谢!

1
反射还提供了访问不可访问类型的方法。 - Hans Passant
还没有完全解决!但我接受了最接近的一个。 - Coopernick
6个回答

8

根据MSDN文档:

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

根据MSDN文档:

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

所以,GetTypes()调用确实会给你一个包含在程序集中所有类型的数组 - 不管它们是否对你可见或可实例化。这可能看起来很奇怪 - 但是如果你想检查自己的程序集(或与你的代码处于同一命名空间的程序集)呢?如果需要,你需要能够查看所有内容。


好的,谢谢你,但我更感兴趣的是从客户的角度来看这个问题的原因 - 如果我构建并发布一个程序集,只有公共接口应该是可发现的。话虽如此,你说得对,检查自己的程序集是必要的。 - Coopernick

4

语言层面上的可见性与反射层面上的类型可见性没有任何关系。

反射的整个概念是,您可以查看所有类型、成员等,并检查它们;例如用于代码生成目的或其他用途。同样,您还有一些场景,例如使用InternalsVisibleToAttribute时以及需要反射自己的程序集时。如果这些不可用,就会大大限制.Net框架,而这些都是完全合法的。

因此,默认情况下应返回所有类型,只有在运行时企图使用类型时才会涉及到可见性。这也可以被绕过;.Net框架本身依赖于某些情况,可以实例化其他程序集的私有类型;并且您还可以跳过自己动态构建的程序集的可见性检查。我在为我们内部应用程序编写的自定义IOC和DI框架中使用此功能,以允许我们的开发人员将类型完全隐藏在外部代码之外,但仍然可以在其应用程序中使用。


1

我正在调查一个与 bug 相关的web API,并发现Assembly.GetExportedTypes和'Assembly.GetTypes`之间有一个非常重要的区别。这在文档中有说明,但不是非常清楚。

Assembly.GetExportedTypes如果无法加载任何依赖程序集,则会抛出“FileNotFoundException”异常。 Assembly.GetTypes会抛出包含成功加载的类型的ReflectionTypeLoadException。因此,如果即使无法加载程序集中的某些类型,您仍想成功,请使用GetTypes而不是GetExportedTypes

这段代码将无法正常工作,因为Assembly.GetExportedTypes不会抛出ReflectionTypeLoadException

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

1

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

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


0

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

那么您也会看到私有和内部的类型,这是合理的。


0
如果您想要获取所有公共类型,可以使用 GetExportedTypes 方法,但如果您还想获取其他所有类型,可以使用 GetTypes 方法。即使一个类型是私有或内部的,您也可以通过反射和动态创建新实例并使用它,因此我认为这两个方法都不会重复。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接