Assembly.GetTypes - why use this if GetExportedTypes is available?
I'm confused about what scenarios you would use one or the other.
If you have an assembly with a some public and private (or internal) types in it, then only the public types should be available from outside. Any types that are internal, or private - should not be available, in fact, their existence should not be discoverable.
Therefore, GetTypes
and GetExportedTypes
- in my mind, should return the same thing.
Clearly I'm thinking about this wrong - what is each 开发者_Python百科one for?
Thanks!
From the MSDN docs:
Assembly.GetTypes Method
Return Value Type: System.Type[]
An array that contains all the types that are defined in this assembly.
From the MSDN docs:
Assembly.GetExportedTypes Method
Return Value
Type: System.Type[]
An array that represents the types defined in this assembly that are visible outside the assembly.
So the GetTypes()
call will indeed give you all types defined in an assembly - whether they're "visible" and instantiable to you or not. Might seem odd - but what if you want to inspect yourself, your own assembly (or an assembly in the same namespace as your code)? You need to be able to see everything - if needed.
Visibility at the language level has nothing to do with type visibility at the reflection level.
The whole idea of reflection is that you can see all types, members etc and inspect them; say for code generation purposes or whatever. Equally you have scenarios such as where the InternalsVisibleToAttribute
is used and, as others have said, when you need to reflect your own assembly. These are all perfectly legitimate and would be made impossible (thereby heavily restricting the .Net framework) if not available.
Therefore the default should be to return all types - only when an attempt is made to use a type at runtime does visibility come into it. It can also be side-stepped; the .Net framework itself relies on some scenarios where being able to instantiate other assemblys' own private types; and you can skip visibility checks on your own dynamically built assemblies too. I use this feature on my own custom-rolled IOC and DI framework written for our in-house applications to allow our devs to make types completely hidden from external code, but still useable within their applications.
GetExportedTypes()
does not include protected/private types. GetTypes()
includes all Types.
Regarding internal
types the MSDN documentation of GetExportedTypes()
is unclear.
I was investigating a web API bug that ran into this and found one very important difference between Assembly.GetExportedTypes
and 'Assembly.GetTypes`. It is in the documentation but is not very clear.
Assembly.GetExportedTypes
throws a 'FileNotFoundException' if any of the dependent assemblies cannot be loaded. Assembly.GetTypes
throws ReflectionTypeLoadException
which 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 use GetTypes
and not GetExportedTypes
.
This piece of code would not work as Assembly.GetExportedTypes
does not throw ReflectionTypeLoadException
.
Type[] types;
try
{
types = assembly.GetExportedTypes();
}
catch (ReflectionTypeLoadException e)
{
types = e.Types;
}
For external assemblies that would indeed be the case, but what if you call GetTypes on your own assembly?
Then you'd see the private and internal ones too, which is logical.
If you want all the public types, you can use GetExportedTypes, but if you want all the other types as well, you can use GetTypes. Even if a type is private or internal you can create new instances and use it via Reflection and Dynamic, so I don't see any of these two being redundant.
精彩评论