My understanding is that the reason why there are raw types and type erasure in Java is that because at the time generics was introduced, there were standard APIs that could not be made generic without breaking existing code.
Generics was also introduced to .NET at some point down the road, but this feature was implemented in a manner that does not rely on raw types or type erasure (and if it does, it does so in a manner that is transparent to the user). So existing APIs remained unchanged (for example, the code in the System.Collections namespace) and new, generic APIs were introduced (for example, the code in the System.Collections.Generic namespace).
So how come Java generics, unlike .NET generics, requires raw types / type erasure?