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

Share this post

Comments (27)

  • Dew Drop – March 13, 2020 (#3153) | Morning Dew Reply

    […] C#: Different ways to Check for Null (Thomas Claudius Huber) […]

    March 13, 2020 at 12:03 pm
  • Joel Reply

    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.

    March 13, 2020 at 4:43 pm
    • Thomas Claudius Huber Reply

      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

      March 17, 2020 at 3:04 pm
    • Chokan Yesmagambetov Reply

      also if(foo is { })

      July 17, 2021 at 1:50 pm
  • The Morning Brew - Chris Alcock » The Morning Brew #2953 Reply

    […] C#: Different ways to Check for Null – Thomas Claudius Huber […]

    March 16, 2020 at 7:00 am
  • Dipo Reply

    Good use of _ = name ?? throw new ArgumentNullException(nameof(name));

    it’s sensible and neat

    March 16, 2020 at 9:11 am
  • Eric Bäckhage Reply

    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/

    March 17, 2020 at 6:25 am
  • Jamie Walters Reply

    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.

    September 11, 2020 at 5:00 pm
    • Thomas Claudius Huber Reply

      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.

      September 12, 2020 at 9:32 am
  • Avi Farah Reply

    Thank you

    September 13, 2020 at 3:21 pm
  • Olivier Jacot-Descombes Reply

    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).

    December 17, 2020 at 6:41 pm
    • Thomas Claudius Huber Reply

      Interesting. Seems to be a shortcut for if (GetValue() is [variabletype] value)

      December 21, 2020 at 3:15 pm
  • Tony L Reply

    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

    January 18, 2021 at 5:59 pm
  • Italo Aguiar Reply

    Another interesting way (not null):
    if (value is { })

    April 14, 2021 at 5:24 pm
  • Mateusz Bogusz Reply

    > 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.

    November 2, 2021 at 7:25 pm
  • EG Reply

    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.

    March 5, 2022 at 8:03 pm
  • Mehdi Reply

    ArgumentNullException.ThrowIfNull(validateMe, nameof(validateMe));

    September 15, 2022 at 3:39 pm
  • HS Reply

    Hi
    Thanks for the article.
    I have seen null == name been used too, Is it somehow better than any other cases

    December 15, 2022 at 5:40 am
    • Thomas Claudius Huber Reply

      That’s OK too, and it’s the original syntax to check for null in C# (and still valid!)

      December 16, 2022 at 10:38 am

Leave a Reply to Thomas Claudius Huber Cancel reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.