My Least Favorite Part of C# Evolution: Inconsistency

Cesar Aguirre - Jul 29 - - Dev Community

I originally posted this post on my blog a long time ago in a galaxy far, far away.

C# isn't just Java anymore.

That might have been true for the early days of C#. But the two languages took different paths.

People making that joke have missed at least the last ten years of C# history.

C# is open source and in constant evolution. In fact, you can upvote and discuss feature proposals in the C# official GitHub repo.

Every .NET release comes with new C# features.

But I've stopped obsessing over new C# features. In fact, I stopped collecting my favorite C# features by version. I feel I'm not missing much.

C# is not a consistent language anymore. We now have many alternatives for the same task.

Since I don't want this post to be only a rant, here are three new C# features introduced in recent versions. I have a love-and-hate relationship with these next three features.

Objects, Arrays, and Null

First, here's how to create a new object,

Movie m = new Movie("Titanic");
var m = new Movie("Titanic");
Movie m = new("Titanic");
//       πŸ‘†πŸ‘†
Enter fullscreen mode Exit fullscreen mode

The last one is the target-typed "new" expressions introduced in C# 9.0. I'm not quite sure if I like this feature or not. While I make my mind, that's one of the features I disable in aΒ .editorconfig file.

Second, here's how to declare and initialize an array,

Movie[] movies = new Movie[] { new Movie("Titanic") };

var movies = new Movie[] { new Movie("Titanic") };
var movies = new Movie[] { new("Titanic") };
//                        πŸ‘†πŸ‘†

var movies = new[] { new Movie("Titanic") };
//           πŸ‘†πŸ‘†

Movie[] movies = [ new Movie("Titanic") ];
//               πŸ‘†
Movie[] movies = [ new("Titanic") ];
Enter fullscreen mode Exit fullscreen mode

We combine "new" expressions and collection expressions introduced in C# 12.

And, lastly, here's how to check if an object is not null,

var titanic = new Movie("Titanic")

titanic != null;
titanic is not null;
titanic is {};
titanic is object;
Enter fullscreen mode Exit fullscreen mode

The first option is the old one. The classic one. The other three are thanks to pattern matching.

And I don't want to touch on primary constructors. It's like classes got jealous of records and started crying for a similar feature, like a baby boy jealous of his brother.

VoilΓ ! That's what I don't like about C#. Don't take me wrong, C# is a great language with excellent tooling. But my favorite features are old: LINQ, async/await, and extension methods.

Some new features have lowered the barrier to entry. Now a "Hello, world" is a single line of code: Console.WriteLine("Hello, world!");.

Other C# features are making the language inconsistent and easier to write but not easier to read.

Often C# doesn't feel like a single language, but three: the classic one from the early 2000s, another one between the classic and theΒ .NET era, and the one we're living these days.

Anyway, still no discriminated unions. Maybe in C# 20?


Whether you're starting out or already on the software engineering journey, join my free 7-day email course to refactor your coding career now-I distill 10+ years of career lessons into 7 short emails. Email #1 could save your next software projects from failure.

Happy coding!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .