C# (.NET) Design Flaws

  • the Reset() method on IEnumerator<T> was a mistake (for iterator blocks, the language spec even demands that this throws an exception)
  • the reflection methods that return arrays were, in Eric's view, a mistake
  • array covariance was and remains an oddity
    • Update: C# 4.0 with .NET 4.0 added covariant/contravariance support to generic interfaces (like IEnumerable<out T> and Func<in T, out TResult>, but not concrete types (like List<T>).
  • ApplicationException rather fell out of favor - was that a mistake?
  • synchronized collections - a nice idea, but not necessarily useful in reality: you usually need to synchronize multiple operations (Contains, then Add), so a collection that synchronizes distinct operations isn't all that useful
    • Update: The System.Collections.Concurrent types, with TryAdd, GetOrAdd, TryRemove, etc were added in .NET Framework 4.0 - though methods that accept a factory delegate do not guarantee the factory will only be invoked once per key.
  • more use could have been made of the using/lock pattern - perhaps allowing them to share a re-usable (extensible?) syntax; you can simulate this by returning IDisposable and using using, but it could have been clearer
  • iterator blocks : no simple way of checking arguments ahead-of-time (rather than lazily). Sure, you can write two chained methods, but that is ugly
  • simpler immutability would be nice; C# 4.0 helps a bit, but not quite enough
  • no "this ref-type parameter cannot be null" support - although contracts (in 4.0) help with this somewhat. But syntax like Foo(SqlConnection! connection) (that injects a null-check / throw) would be nice (contrast to int? etc)
    • Update: This is fixed in C# 8.0.
  • lack of support of operators and non-default constructors with generics; C# 4.0 solves this a bit with dynamic, or you can enable it like this
  • the iterator variable being declared outside the while in the foreach expansion, meaning that anon-methods/lambdas capture the single variable, rather than one per iteration (painful with threading/async/etc)
    • Update: This was fixed in C# 5.0.

TextWriter is a base class of StreamWriter. wtf?

That always confuses me to the extreme.


A small C# pet peev - constructors use the C++/Java syntax of having the constructor be the same name as the class.

New() or ctor() would have been much nicer.

And sure, tools such as coderush make this less of an issue for renaming classes, but from a readability POV, New() provides great clarity.

Tags:

C#

.Net