2021-10-04

What is wrong with C#

This is part of a series of posts in which I am documenting what is wrong with certain popular programming languages that I am (more or less) familiar with.  The aim of these posts is to support a future post in which I will be describing what the ideal programming language would look like for me.  

I will be amending and revising these texts over time.

What is wrong with C#:

  • The garbage collector.
  • Curly braces.
  • Member initializers execute in a static context. 
    • This is far worse than just not having access to constructor parameters; This renders the language almost unusable.
  • Delegates are superfluous and problematic.
    • They could have been implemented as single-method interfaces, as java does, thus keeping the language simpler.
    • The ability to have an anonymous method implementing a delegate is far less useful than the ability to have an anonymous class implementing an interface.
  • The built-in collection model is lame:
    • Arrays implement the `IList` interface, which might seem like a great idea, until you realize that `IList` has `Add()`, `Insert()` and `Remove()` methods, which of course cannot be honored by an array.
    • The `IReadOnlyList` interface is not a super-interface of `IList`. It does not even have an IndexOf() method.
    • Enumerators still have to implement the legacy, non-generic `GetEnumerator()` method.
    • Fluent style (Linq) is limited to working almost exclusively with `IEnumerable<>`.
  • Built-in events are problematic.
    • If one event handler throws, the rest will not be invoked.
    • If one event handler causes another event handler to be removed, the removed event handler will still be invoked.
    • An event is a special kind of thing which cannot be passed to a function, not even by reference. (As all properties are.) As a result, you have to always hand-code the addition of a handler to an event, and to also separately hand-code the corresponding removal. It is absolutely impossible to pass an event to a function, along with a handler and a boolean flag specifying whether to add or remove the handler. This makes it impossible to gather all symmetric initialization and cleanup operations in one place, which in turn leads to buggy software.
    • Events are unsuitable as a language feature and should have been left for the runtime library to implement.
  • Collecting a stack trace is a ridiculously slow operation.
  • Throwing an exception is a stupendously slow operation.
  • Certain things about the runtime are completely bonkers, for example:
    • The notion of a "current directory", which is a piece of global state shared across all threads, and even across all appDomains within a process.  (So much for appDomain isolation.)
    • The behavior of the ThreadAbortException.
  • No compiler-enforced function purity.
  • No compiler-enforced immutability.
Feedback is more than welcome: you'd be doing me a favor. However, be aware that blogger sometimes eats comments, so be sure to save your text before submitting it. If blogger eats your comment, please e-mail it to me.

No comments:

Post a Comment