Turns out Microsoft detected that our specific app was asking, and lied to it, because telling it the truth broke the previous version of our app (because the previous version didn't know about the new version of Windows). It was annoying, and yet still incredibly impressive that Microsoft knew who we were and was going out of their way to try not to break us.
I remember hearing epic stories from ex-MS coworkers about the internals of CreateFile/Read/etc. All sorts of convolutions to keep back compat with things from the win31 and earlier days. Painful to work on as a developer but great for customers.
Java couldn't do generics right, for example, because they didn't want to break compatibility. C# seems to be adding a lot of improvements, but would it be better if they could break compatibility?
The reason is that C# had a chance to learn from the experience of others and is still a relatively new language.
There is a little bit of cruft here and there. For example, ,NET had good threading support from the start, but the idioms that are used nowadays for concurrent and parallel programming have evolved, and while the old APIs are still there, developers now use APIs that are more up to date.
[1] https://gist.github.com/olmobrutall/31d2abafe0b21b017d56
Seems to go against null propagation operator though :)
> That would be huge, and worth any amount of hit.
I'm open to the idea that non-nullable references (by default) could 'be worth any hit', but I'd like to see the evidence. Have you tested converting a large codebase to non-nullable, and seen a reduction in errors as a result?Anecdotally I've noticed a reduction in these kinds of issues when using languages that use non-nullable references by default (F#. Haskell, etc.). I find I am much more confident as a programmer when nullable references aren't the default. Actually a few days ago we had our first null reference error in F#, and it was because the record type passed to an F# function was instantiated in C#.
If you think about it, the idea that a statically typed system lies to you about the contract that a value will honour is always going to be a source of bugs. It takes static languages back into the realm of dynamic languages.
Well yes, I'm sure you have, but were those replaced by other bugs, leaving the bug count the same?
The only two warts that strike me off-hand are covariant arrays and System.Nullable being value-type only.
Overall Microsoft has done a great job of building on earlier decisions. Including functions as first-class types (System.Delegate) in V1 is probably the biggest and was a deliberate break with Java's approach. It has enabled a ton of features: lambdas, LINQ, Expression, etc. The fact that LINQ can be turned into an AST with Expression<T> means you can also construct code dynamically at a much higher level than IL.Emit() while delegates mean you can get the JIT to provide the equivalent of a function pointer to the native code.
https://blogs.msdn.microsoft.com/dsyme/2011/03/15/netc-gener...