Are you using some sort of obfuscator or optimiser (e.g. Dotfuscator) that could be removing the types because it thinks they are unused? If so, you will have to configure that software so that it doesn’t remove them. That is not a C# compiler issue.
Otherwise, I have never seen this myself. All the types are always present in the assembly, even if they are not referenced. Anything else would be nuts because it would make Reflection really useless as you noticed.
So to test this, I just compiled a small project with two unused classes, and one class that is only used by one of the unused classes. None of them got removed, even in Release mode and even with “optimizations” enabled.
If you can provide a small example where the compiler does remove a type, it would probably be a compiler bug and you should perhaps consider reporting it to connect.microsoft.com.