Such is life on Twitter, I’ve been watching from afar .NET developers argue about a particular upcoming C# 11 feature, Parameter Null Checks. It’s actually just a bit of syntactic sugar to make it easier to throw argument null exceptions, but it’s caused a bit of a stir for two main reasons.
People don’t like the syntax full stop. Which I understand, but other features such as some of the switch statement pattern matching and tuples look far worse! So in for a penny in for a pound!
It somewhat clashes with another recent C# feature of Nullable Reference Types (We’ll talk more about this later).
First let’s look at the problem this is trying to solve.
I may have a very simple method that takes a list of strings (As an example, but it could be any nullable type). I may want to ensure that whatever the method is given is not null. So we would typically write something like :
void MyMethod(List<string> input)
if(input == null)
throw new ArgumentNullException(nameof(input));
Nothing too amazing here. If the list is null, throw an ArgumentNullException!
In .NET 6 (Specifically .NET 6, not a specific version of C#), a short hand was added to save a few lines. So we could now do :
void MyMethod(List input)
There is no magic here. It’s just doing the same thing we did before with the null check, but wrapping it all up into a nice helper.
So what’s the problem? Well.. There isn’t one really. The only real issue is that should you have a method with many parameters, and all of them nullable, and yet you want to throw a ArgumentNullException, you might have an additional few lines at the start of your method. I guess that’s a problem to be solved, but it isn’t too much of a biggie.
Parameter Null Checking In C# 11
I put C# 11 here, but actually you can turn on this feature in C# 10 by adding the following to your csproj file :
Now we have a bit of sugar around null check by doing the following :
void MyMethod(List<string> input!!)
Adding the “!!” operator to a parameter name immediately adds an argument null check to it, skipping the need for the first few lines to be boilerplate null checks.
Just my personal opinion, it’s not… that bad. I think people see the use of symbols, such as ? or ! and they immediately get turned off. When using a symbol like this, especially one that isn’t universal across different languages (such as a ternary ?), it’s not immediately clear what it does. I’ve even seen some suggest just adding another keyword such as :
void MyMethod(notnull List<string> input)
I don’t think this is really any better to be honest.
Overall, it’s likely to see a little bit of use. But the interesting context of some of the arguments against this is….
Nullable Reference Types
C#8 introduced the concept of Nullable Reference Types. Before this, all reference types were nullable by default, and so the above checks were essentially required. C#8 came along and gave a flag to say, if I want something to be nullable, I’ll let you know, otherwise treat everything as non nullable. You can read more about the feature here : https://dotnetcoretutorials.com/2018/12/19/nullable-reference-types-in-c-8/
The interesting point here is that if I switch this flag on (And from .NET 6, it’s switched on by default in new projects), then there is no need for ArgumentNullExceptions because either the parameter is not null by default, or I specify that it can be null (And therefore won’t need the check).
Just as an example, with Nullables switched on using code :
void MyMethod(List<string> input)
//Input cannot be null anyway. So no need for the check.
void MyMethod2(List<string>? input)
//Using ? I’ve specified it can be null, and if I’m saying it can be null…
//I won’t be throwing exceptions when it is null right?
There’s arguments that nullable reference types are a compile time check whereas throwing an exception is a runtime check. But the reality is they actually solve the same problem just in different ways, and if there is a push to do things one way (nullable reference types), then there’s no need for the other.
With all of that being said. Honestly, it’s a nice feature and I’m really not that fussed over it. The extent of my thinking is that it’s a handy little helper. That’s all.