Visibility at the language level has nothing to do with visibility at the reflection level.
The whole idea of thinking is that you can see all types, members, etc. and check them out; let's say for the purpose of generating code or something else. Similarly, you have scripts, for example, when using InternalsVisibleToAttribute and, as others have said, when you need to mirror your own assembly. All of them are completely legal and will be impossible (thereby severely restricting the .Net infrastructure) if they are not available.
Therefore, by default, all types should be returned - only when trying to use the type at runtime makes visibility available. It can also be stepped; the .Net infrastructure itself relies on some scenarios in which you can create instances of other native assembly types; and you can also skip visibility checks on your own dynamically built assemblies. I use this feature in my own IOC and DI applications written for our internal applications so that our developers can completely hide types from external code, but can still be used in their applications.
Andras zoltan
source share