Generics were a cutting-edge feature in 2005. Microsoft took the opportunity to start from scratch, and released the .Net Framework 2.0 without backwards-compatibility, and with full support for generics. A List<String> is actually a List of String.
When Sun released Java 5, they didn't want to disrupt the established Java ecosystem. Their implementation is called "type erasure". As an example, List<String> is actually just List<Object>, with automatic runtime typecasting to String. https://docs.oracle.com/javase/tutorial/java/generics/erasur...
Java's solution works well enough, but it breaks down in certain scenarios, such as multiple levels of generics. For example, when getting an element from a List<List<String>>, Object is not cast to List<String> (which doesn't really exist), but merely List.
C#'s implementation of generics became even more sophisticated with C#4, which introduced covariance and contravariance. https://msdn.microsoft.com/en-us/library/ee207183.aspx