C#: Different ways to Check for Null
What is the classic way to check if for example a parameter value is null
? If you’ve developed with C# since a while, you might be familiar with this classic syntax:
public static int CountNumberOfSInName(string name)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
return name.Count(c => char.ToLower(c).Equals('s'));
}
Since C# version 7 you can use the is
keyword for the null
check like in the snippet below:
if (name is null)
{
throw new ArgumentNullException(nameof(name));
}
But with C# 7, there’s even a shorter syntax. Discards were also introduced. They are unused and ignored variables that are represented in your code with an underscore (_). In combination with the Null-coalescing operator (??) you can write the null check like this:
_ = name ?? throw new ArgumentNullException(nameof(name));
That means, the whole method looks just like this:
public static int CountNumberOfSInName(string name)
{
_ = name ?? throw new ArgumentNullException(nameof(name));
return name.Count(c => char.ToLower(c).Equals('s'));
}
To be honest, I really like the last approach using the discards, but maybe for some developers it’s too much. I think the is
keyword is very clear and readable. It is my favorite.
The is
keyword has also the big advantage that it ignores any ==/!= operator overloads on the specific class. It will do a null
check, no matter if there’s an operator overload or not. That makes it better than just using ==. You can read more about this in this blog post.
The Is Keyword And the Not Pattern in C# 9.0
With C# 9.0, you can combine the is
expression with the logical not
pattern, which is powerful if you want to check if an object is NOT null. Before C# 9.0 you had to use the is
expression like below to check if an object is not null:
if (!(name is null)) { }
Some developers preferred the following syntax to check if the name is not null:
if (name is object) { }
But the statements above are neither very readable nor easy to understand. That’s why many developers still prefer the classic way:
if (name != null) { }
But since C# 9.0, you can write that not null check like below, and I think that is really readable code:
if (name is not null) { }
Summary
So, with C# 9.0, you can write your null / not-nulll checks like below, and I think that’s readable:
if (name is null) { }
if (name is not null) { }
Happy coding,
Thomas
Comments (27)
[…] C#: Different ways to Check for Null (Thomas Claudius Huber) […]
When you want to check for not-null, you can do..
if (foo != null)
if (!(foo is null))
if (foo is object)
I prefer the third because it’s clear and concise and doesn’t involve negation or nested parens.
Hi Joel,
yes, that’s super cool. I really like “foo is object”, but I guess it’s not as obvious as !(foo is null)
Best would be
if(foo is not null)
But we don’t have that (yet?).
Thomas
also if(foo is { })
[…] C#: Different ways to Check for Null – Thomas Claudius Huber […]
Good use of _ = name ?? throw new ArgumentNullException(nameof(name));
it’s sensible and neat
Thanks Dipo. :)
Yes, it is. I like it too.
I like the ’is’ variant. Hopefully, with the nullable reference types introduced in C#8 we’ll be able to get rid of null-guards like these.
If there is a need to represent the possible abscence of a value I prefer the Option type. I wrote a blog post on this topic that you might find interesting, see https://ericbackhage.net/c/nullable-reference-types-compared-to-the-option-monad/
Hi Eric,
yes, with nullable reference types we should be able to reduce these null-guards in our code.
Thank you for sharing that blog post, it’s a great read!
Thomas
Unfortunately all NRTs bring to the table are compile-time checks that you are putting your null-guards in :)
Thanks for the post Thomas. A quick update for those coming across this article at a later date.
The new C# 9 patterns will bring ‘is not null’, yay! (https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/patterns3.md#pattern-combinators).
But we’ll have to wait and see whether Simplified Null Argument Checking will make it into a release https://github.com/dotnet/csharplang/blob/master/proposals/null-arg-checking.md.
Thank you Ben, the new C# 9 patterns are really a great addition to the language.
Thanks Thomas. I had the following piece of code that does a null check within a Ternary Expression:
private static string GetAttributeValue(Assembly assembly)
where T : Attribute
{
var type = typeof(T);
var attribute = assembly
.CustomAttributes
.Where(x => x.AttributeType == type)
.Select(x => x.ConstructorArguments.FirstOrDefault())
.FirstOrDefault();
return attribute == null ? string.Empty : attribute.Value?.ToString();
}
When I updated this to change the line that was attempting a null check to
return attribute is null ? string.Empty : attribute.Value?.ToString();
The compiler explained to me that I am trying to do a null check against a non-nullable value type. By attempting this, I realized the null check was not necessary after confirming the type System.Reflection.CustomAttributeTypedArgument is a non-nullable struct.
So the offending line can be simplified to
return attribute.Value?.ToString();
And this can be simplified to
return attribute.Value.ToString();
Since System.Reflection.CustomAttributeTypedArgument.Value cannot be null.
Does this seem accurate to you? Point of sharing this is to demonstrate after going through a code base to update null checks, I learned something the code was doing that is not necessary: a null check against a non-nullable value type.
Hey Jamie, yes, your adjustments looks accurate to me. I see a lot of code that does null checks against value types that can not be null. :-) Usually you find these also in the warnings of the compiler.
Thank you
You’re welcome! Thank you Avi.
In C# 9.0 you can also test for not null with an empty property pattern. This is useful when you want to assign the result to a variable `if (GetValue() is { } value)`. (But `is not null value` does not compile).
Interesting. Seems to be a shortcut for
if (GetValue() is [variabletype] value)
OHHHH you need c# 9.0 for the “is not null” keywords to work.
I was wondering why it was giving me weird results on my Unity project.
Thanks for your insight. Cheers
Hi Tony, excactly. C# 9.0 rocks it. :)
Another interesting way (not null):
if (value is { })
Absolutely, that one is great too. :-)
> The is keyword has also the big advantage that it ignores any ==/!= operator overloads on the specific class. It will do a null check, no matter if there’s an operator overload or not.
Bill Gates once said in an interview that he envied Steve Jobs’ taste for choosing simple solutions. Bill Gates hasn’t been running Microsoft for a long time, and certainly not .NET development. But I see that his followers have inherited the same traits.
Hi
Thanks for the article. When I do this:
Student jewll = new student();
I noticed that jewell is NOT NULL, and since it does not have a value, what does it contain? How could I tell it was never had any of its properties assigned a value since it was created? Thanks.
ArgumentNullException.ThrowIfNull(validateMe, nameof(validateMe));
Hi
Thanks for the article.
I have seen null == name been used too, Is it somehow better than any other cases
That’s OK too, and it’s the original syntax to check for null in C# (and still valid!)