Why C# 10 is pretty irrelevant (but .NET 6 isn't) and why that's a good thing
I hope the title got you intrigued. Usually there's a lot of excitement when a new language version comes out, as people are waiting to see what cool new feature will improve their daily development practice.
As a book author, I have to be particularly aware of new language features; over the last few weeks I've been working on the 2nd Edition of my book, Functional Programming in C#, so I've been watching the evolution of .NET 6 and C# 10 closely (publishing a book is a long process, and you don't want your book to be obsolete by the time it comes out!).
Why is .NET 6 important?
As I was watching these developments, I realized that .NET 6 is quite an exciting target, for one thing, because it's the first of the "new" cross-platform .NET version (supplanting the old .NET Framework vs .NET Core dichotomy) to have LTS. In other words, .NET 6 is going to be the version of reference for the next few years.
But another aspect of .NET 6 that I found very exciting and that motivated me to target .NET 6 in my book (already several months ago, when it was still in beta) is that it includes minimal APIs. Minimal APIs allows you to write Web APIs in a functional style — one endpoint, one function.
Web APIs are, of course, a very important part of .NET development, and one of the hurdles in the first edition was to demonstrate how to write a Web API in a functional style, given that ASP.NET was so biased towards MVC, which is inherently object-oriented. You had the language features to program functionally, but the framework was against you. Minimal APIs changes everything in this respect: now you have not only language support, but also library support to write a Web API in a functional style!
And, while I'm on the subject, in response to those that criticized minimal APIs (and top-level statements — a feature of C# 9) for encouraging a one-file mess: your point is moot. There are many ways of modularizing an application, MVC is not the only one! You can use minimal APIs and top level statements and still organize your code in a very effective and granular way, the way node.js developers have for a decade. The fact that it's different from MVC and that you may not be familiar with it is no excuse.
In summary, I think .NET 6 important
- in general, as a milestone in the evolution of .NET
- in the context of functional programming, because it allows you to write Web APIs in a functional style
C# versions leading up to 10
Now let's turn to C# 10, which as you know is being released along with .NET 6. Think about the 3 preceding versions and their most important features:
- C# 7 — tuples
- C# 8 — pattern matching (ok, it was introduced to some extent in previous versions, but it's only with
switchexpressions in C# 8 that pattern matching comes into its own)
- C# 9 — records (easy-to-write immutable data types)
These features are all staples of functional languages, meaning that the evolution of C# over the last several versions has been from a multiparadigm-but-mostly-OO language towards a truly multiparadigm language capable of supporting a functional programming style (as well as the original imperative and object-oriented style).
As I was writing the 1st edition of my book (around the time C# 7 was being developed) I had to jump through hoops to demonstrate functional programming in C#: I had to bend and twist the language to my will. So the 2nd Edition has been mostly about simplifying removing stuff: you now have language support for most functional programming techniques in C#!
Of course, as these features were being added to the language, many programmers complained that C# was getting too feature-rich, hence too complex and lacking in identity. To a certain extent I agree; it would be best to pick the best language for the programming job at hand, and have an opinionated language that makes it easy to do the right thing. But the reality is that life is full of compromises and that often your employee picks your language for you, or some other constraints dictate your choice of language.
So the reality of C# today is that it's indeed a very complex and very feature-rich language. I doesn't mean it's dying; I would say that it now demands that the development team make some choices on how they want to use the language. I would almost say that you have to commit to using a subset of C#, not the whole language. Of course, in my book I argue that for most programming tasks you should use the subset of features that allow you to program in a functional style: stateless static classes, records, extension methods, etc while staying away from things like abstract classes, mutable variables, iteration, etc. The fact that the language is feature-rich means that it can also be used to write low-level, high-performance programs where in-place updates and even unsafe pointer access are justified.
C# 10 features
Let's now look at some of the actual features confirmed for C# 10.
- Record structs. C# 9 introduced records, which were reference types, so this feature generalizes the record syntax so that it can be used for value types as well. (So you could say that this feature "completes" the work done in C# 9)
- Improvements to structures types, mostly meaning that you can use
withexpressions to create modified copies of any struct (again encouraging you to work with immutable data).
- Global using directives.
usingdirectives are per file; now you can make them per project. This means that commonly imported namespaces (like
System.Collections.Generic, etc) don't need to clutter your imports sections, which will now show just the stuff that is relevant for a specific file. Used right, it reduces duplication and helps you to concentrate on what matters.
- File-scoped namespace declaration. Declares the namespaces for the contents of your file. Ends in a semicolon, therefore reduces indentation, a welcome change.
So far, nothing revolutionary. There are several other features, but they're even less impressive; the full list of features can be found here. If it's true that C# has become too complex and feature-rich, then the fact that the new features of C# 10 are minor and effectively refinements and logical extensions of features of previous versions should be welcome.
I hope these scattered thoughts have given you some food for thought. Please consider checking out my book on Functional Programming in C# (some of the content is freely available) to learn more about making the best of your C# coding experience!