In this blog post we will make a small excourse to new features which might come in the close or distant feature of the C# language. The base for all of this is the csharp-repository. The repository contains proposals as well as inactive or rejected ideas. The markdown files are only half the truth. I'd recommend you to checkout the issue tracker to see how a feature evolved over time. Let's dive right in:
Compound assignment in object initializer and with expression
The idea behind this proposal is to make object initializer a bit more versatile. In its current state you are only allowed to have simple assignments like that:
var timer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(5);
};
// We have to define the lambda function outside of the object initalizer
timer.Tick += (s, e) => { ... };
The proposal exactly wants to tackle that behavior:
var timer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(5);
timer.Tick += (s, e) => { ... }; // This is now allowed
};
The same for the with
expression, where you can directly make compound assignments:
public record Person (string Name, int Age);
var steven = new Person("Steven", 30);
var stevenButOneYearOlder = steven with { Age += 1; };
The main benefiter from this request would be a lot of UI frameworks where event-wiring is key.
Source: https://github.com/dotnet/csharplang/issues/5176
Discriminated unions
Using discriminated unions seems a bit weird for an OOP language, but still there are valid uses cases. Let's just check shortly what discriminated unions are. For that I'll showcase some Typescript code.
interface Cat {
weight: number;
whiskers: number;
}
interface Dog {
weight: number;
friendly: boolean;
}
let animal: Dog | Cat;
The first thing to understand is, that it is not about the common subset between dog and cat. You can better understand this as animal
has to be either Dog
or Cat
. But not only that you could also derive from Dog
and make a ShibaInu : Dog
class, which fulfils the requirements.
Source
With that you can do stuff like this:
if ("friendly" in animal) {
console.log(animal.friendly);
} else {
console.log(animal.whiskers);
}
Of course to keep it short, I'll just provide you some links to get a better understanding what a discriminated union is and what the usage is. So here, here and a very beautiful example here.
Source: https://github.com/dotnet/csharplang/issues/113
field
keyword - semi auto-properties
This one might even come with C# 11. There is a strong indication because there is a feature branch in the roslyn repository which does translate that keyword correctly. I swear a few days ago even on main
it worked but they seemed to remove it.
The idea is to make auto-properties even better in the sense that you need less code in some scenarios.
In the current world we have that (C# 10):
public class MyClass
{
private string _myString;
public string MyString
{
get => _myString;
set => _myString = value ?? throw new ArgumentNullException;
}
}
With the new field
keyword it looks like that:
public class MyClass
{
public string MyString
{
get => field;
set => field = value ?? throw new ArgumentNullException;
}
}
The compiler does automatically create the backing field for us. No need to explicitly use it. We have the full control via the field
keyword to use it.
Source: https://github.com/dotnet/csharplang/issues/140
ConfigureAwait(false)
on assembly level
The next one is a small helper. Basically when you write a library which handles async code the norm is to use await SomeAsyncOp().ConfigureAwait(false);
. So this ConfigureAwait(false)
stuff will be everywhere because this is what you want as a library maintainer. The proposal would tackle that in the sense, that you can specify via assembly attribute that the compiler should automatically add ConfigureAwait(false)
on every await
call.
Source: https://github.com/dotnet/csharplang/issues/2542
Exponentiation operator
JavaScript / TypeScript has it, Python has it, F# has it and even VB.NET has it: The exponentiation operator.
Often times like this: **
. So instead of var number = Math.Pow(4, 3);
you can simply write: var number = 4 ** 3;
. You could ask, is this really better? And I want to quote Jeffrey on the issue tracker:
Exponentiation is no different from addition or multiplication: it is a common mathematical operation for which there is a universal notation (including precedence rules) that is approximated in programming languages.
This feature would also go really good with the new generic math feature.
Source: https://github.com/dotnet/csharplang/issues/2585
Conclusion
5 nice features. Is there any of those you want to have rather yesterday than in an upcoming version? Let me know. And also let me know if I missed a crucial proposal.