Coding, Tech and Developers Blog
Every year, Microsoft releases new features for the C# language. For those of you interested in what direction the lead architects are taking us, let's take a look at what has been recently presented on Microsoft Build 2024.
Whether you are new to the .NET ecosystem or among the long-time participants, whether you are stuck on a legacy system using a very old C# language version or always trying out the latest stuff on greenfield projects - whatever your mileage may be, staying up to date is a good idea. Being a self-employed consultant, this is definitely healthy advice for me.
Every year, the C# language's architects Mads Torgersen and Dustin Campbell give us a quick tour of upcoming features for the next version of C#. If you did not find the time to watch that, I'll give you a roundup. And since one of the features sparks a small debate among software enthusiasts, I also want to shed some light on that.
You can find the original talk here on YouTube as well as the latest feature announcements here (which will of course change over the next few months).
Since these features are partly still built from feature branches only, I will not provide a GitHub repo this time to try things out.
params
collectionsThis is a very simple one so we will not spend too much time on it:
We are all very familiar with the params
syntax, which lets you pass any number of arguments of a certain type into a method:
public void AddItems(params Item[] items) { ... }
C# 13 will add additional overloads to this signature:
public void AddItems(params IEnumerable<Item> items) {...}
public void AddItems(params IReadOnlySpan<Item> items) {...}
Why is that a good thing? Because it will let you pass collections of arguments into those methods without additional allocation overhead. Any package dependencies that support C# 13 will then automatically benefit from the compiler choosing the most efficient overload in your code on rebuild.
We all know auto-properties which is probably the way we are most often writing our properties these days:
public string Name { get; set; }
This is syntactic sugar for us lazy developers, implicitly instructing the compiler to create backing field and property for us. But what if we ever wanted to just slightly change or validate the value upon setting? Well, we'd write all of that backing field code ourselves again. This can be pretty annoying and repetitive work, so the team did something about it:
public string Name { get; set field => value.ToLower(); }
C# 13 will introduce a new keyword field
that represents the backing field that will be generated by the compiler and makes it accessible for us to use in the short-hand notation.
But what if you had an actual field already in your class with this exact same name? Then this will be a breaking change - please be aware of that.
Many of us will know classic extensions that let us define additional instance methods to existing types:
public static class StringExtensions
{
public static class MyExtensions
{
public static int WordCount(this string str)
{
return str.Split(new char[] { ' ', '.', '?' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
And there is already a heated debate around those - people hate or love them for different reasons.
Personally, I am a fan of them whenever they help me wrap convenience code, like parsing, argument conversions, and plain mappings. The only thing I never use extension methods for is business logic.
For example, I would not want to be able to call a business method ToCustomerDiscount()
on every string object in my application. That is logic that belongs to a custom class within my code, which is already in my control, so there is no need for an extension method in the first place.
But what if I wanted to add a static method to an existing type? Or properties? This will be made possible (potentially) in the upcoming version of C# and I'll borrow the example from the above-mentioned talk:
implicit extension JsonString for string:
{
public JsonElement ParseAsJson() => JsonDocument.Parse(s.Trim()).RootElement;
public static string CreateIndented(JsonElement element)
=> element.ValueKind != JsonValueKindUndefined
? JsonSerializer.Serialize(element)
: Empty;
}
explicit extension Customer for JsonElement
{
public string Name => this.GetProperty("name").GetString()!;
}
What are are seeing are type definitions that let us add functionality to existing type that we do not have access to, like string. Compared to extension methods, we are not limited to instance methods but we can also add properties and static type methods.
The fact that they are implicit
indicates that these methods will be present on all string
in our code. In the case of the extension for JsonElement
the extension is marked as explicit
means that it will only be accessible to us once we cast a JsonElement to this type definition:
JsonElement jsonElement = ...;
Customer customer = jsonElement;
var name = customer.Name;
This is essentially a way of looking at an object through a specific set of glasses.
If you are now thinking "Inheritance?", then the answer is not really
, because it is a much more efficient, non-allocating, no-overhead way of accessing the underlying object.
One interesting thing happens when we imagine an extension without actual method or property declarations:
public explicit extension DataSet<T>
for System.Collections.Generic.Dictionary<string, T> { }
This is now essentially an alias
. But since it is actually more of a type definition, it does actually support generics (which alias
does not). We can also better control where and how that extension can be used (which alias
is permitted through a questionable global
keyword).
C# 13 (accidentally, somehow) both improves the way we can use extensions in the future and also gives us a much better alternative to alias
which is kind of a dead end anyway to many of us.
As mentioned, there is already an ongoing debate on social media around this feature. People are complaining that C# is being turned into a typescript clone, with extensions watering the purpose of object-oriented programming.
Me, personally, I can definitely see the benefit of extensions and I can only appreciate the work that Mads and his team are putting into the language to make it the best tool for our job.
At the same time, I can also see how misuse of extensions can lead to creating a mess of an application, hiding business decisions in every small pothole of a code base. But obviously, every tool that we are using is usually meant to solve a very specific job, not all of them.
So know your tools, and you'll be alright. Trust me.
This was a short summary of the feature announcement for C# 13 that was given on Microsoft Build 2024. I do hope that there were one or two interesting bits for you to it!
Be the first to know when a new post was released
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.