DEV Community

Cover image for My Least Favorite Part of C# Evolution: Inconsistency
Cesar Aguirre
Cesar Aguirre

Posted on • Originally published at canro91.github.io

My Least Favorite Part of C# Evolution: Inconsistency

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!

Top comments (6)

Collapse
 
ilya-chumakov profile image
Ilya

How about ref struct? Despite the fact that this naming makes sense in terms of byref pointers, I wish the C# team would come up with something less misleading in a language that also has reference types.

Collapse
 
canro91 profile image
Cesar Aguirre

Yeah! For me that's one of those very niched down language features. I've rarely used it.

Collapse
 
dennis_d150c9 profile image
Dennis E
  • The problem with 'var' is that it doesn't work with fields. Target-typed "new" expressions do.

  • What I find troublesome are different features that have the same syntax. Primary constructors is one of them. Take Person(int age, string name) for example. When Person is a regular class, this means one thing. When Person is a record, it means something else. Don't get me started on the difference between int? and string?

  • Disciminated Unions. They are actually working on it right now.

Collapse
 
canro91 profile image
Cesar Aguirre

The problem with 'var' is that it doesn't work with fields.

Good point!

What I find troublesome are different features that have the same syntax.

Yes, yes, yes! That's why I don't like primary constructors. They look the same as records but work different. Arrrggg!

Disciminated Unions.

Yeah, I saw the proposal about discriminated unions and a post about it is on the way!

Thanks for your comment.

Collapse
 
andychiare profile image
Andrea Chiarelli

I used to think that C# was moving more towards JavaScript.
Now I'm not sure anymore. JavaScript is less confusing...

Collapse
 
canro91 profile image
Cesar Aguirre

Yeah, I think C# is like 3 languages: one pre-2010's, one before the .NET Core era, and the one we're living now :) JavaScript async/await look like the C# ones, so probably some languages are copying the best bit from others. Some C# features are inspired by F# (records for example)