In fact, C# deals excellently with legacy code. While, unlike the JVM, .NET is not binary backward compatible (allowing some excellent language improvements that Java still has not managed to pull off), it is nearly (but not entirely) source code backward compatible. Sure, this allows to old code using old constructs to stay alive, but it works. That alone is pretty unique, especially if you see that nearly any other language either does not manage to move its community to the next version with breaking changes (Python 3, PHP 6) or has tons of compatibility issues every time something changes (Ruby, Scala), or simply is at a standstill (Java).
Having to deal with a DictionaryBase child class which was made before generics were added is way less of a deal than not being able to upgrade your software to the newest version of the language at all. Which is what would've happened if this was done like Scala. Or, if it was done like Java, we'd still be hacking DictionaryBase child classes.
I'd maintain that no language/platform deals with legacy code better than C#.
A lot of hosting environments like Google AppEngine still do not support Python 3. The "there's going to be no 2.8" PEP might help that, though. We can only hope.
In fact, the "big breakage" in Scala everyone loves to cite was the addition of better collections. Just like C# did in 2.0 and now finally drops the old non-generic ones with WinRT/Metro.
The reason it gets so much flack is that Java developers want _binary compatibility_, because that's what they are accustomed to and Scala gets often used by Java developers. Java developers would target the same criticism towards C# if it would run on the JVM.
I take the part on Scala back.
You can do a fair amount of relatively frictionless null handling with extension methods. If that helps.
This will work.
andand negates the need for an explicit null check on each property in a property lookup chain, which would normally be required to avoid a potential NoMethodError or NullReferenceException.
You can create something similar [2] to andand in C# if you are willing to do property lookups using lambda expressions.
-It's wordy. The var keyword was a step in the right direction, but there's still a lot of redundant type information, even compared to other statically typed languages like Go or F#.
-Legacy code. A lot of things that are concise and easy in C# 3.5+ were possible but hideous in older versions. Sadly, that code must still be maintained.
-Null handling. Like another commenter, I wish the language would help more with null values. I'd love an operator to do monadic null coalescing: var foo = thing1.thing2.thing3.bar; Sometimes I want foo to be null if any of the chained objects are null.
It's a pretty good language, though. I'm looking forward to the Roslyn API to the compiler: http://msdn.microsoft.com/en-us/hh500769