Other C# 2.0 features added capabilities to existing features:
⮚Getter/setter separate accessibility
⮚Method group conversions (delegates)
⮚Static classes
⮚Delegate inference
While C# may have started as a generic Object-Oriented (OO) language, C# version 2.0 changed that in a hurry. With generics, types and methods can operate on an arbitrary type while still retaining type safety. For instance, having a List lets you have List or List and perform type-safe operations on those strings or integers while you iterate through them. Using generics is better than creating a ListInt type that derives from ArrayList or casting from Object for every operation.
C# version 2.0 brought iterators. To put it succinctly, iterators let you examine all the items in a List (or other Enumerable types) with a foreach loop. Having iterators as a first-class part of the language dramatically enhanced readability of the language and people's ability to reason about the code.
And yet, C# continued to play a bit of catch-up with Java. Java had already released versions that included generics and iterators. But that would soon change as the languages continued to evolve apart.