Welcome to the world of iterative, cross-team design.
The .Net team isn't just one team. It's a CLR team plus a compiler team plus a framework team plus an IDE team. Each has their own set of budgets, deadlines, requirements, technical restrictions... the works.
Whenever you see a WTF, it'd not a "durrrrrr", but a balance of time and resources to get a product out the door. Some challenges are easy in some areas and hard in others. There is a TON of legacy stuff laying around from 1.0 and 1.1 when they didn't have access to generics. It would have been nice to have them in the first go-around, but it wasn't in the cards. That said, it's beyond outstanding that the 2.0 runtime supports as much extensibility as it does. There's been nothing but patches to the runtime, and the base framework at large, since, oh, mid-2004. They prioritized getting things out like anonymous delegates, generics, etc., which led to such innovations as Linq, functional language support and dynamic runtimes.
The language and framework designers are constantly measuring user requirements up against resource considerations to get you the best bang for the buck. You may see something that looks like a WTF, and sometimes it truly is a questionable decision, but most of the time it's a simple matter of, "this is what we could afford to get out to you when you needed it." I, for one, could not have waited until late-2008 to get this framework.