DEV Community

loading...
Cover image for C# : Avoid == && != to check for nullability

C# : Avoid == && != to check for nullability

pollobatgit profile image dexter ・2 min read

In everyday programming, we have to do something like the following because we don't want to see the ugly NullReferenceException

var car = new Car();

if(car != null) 
{ 
    // invoke method on car variable 
}
Enter fullscreen mode Exit fullscreen mode

Every programmer knows it's the right approach to avoid NullReferenceException.

But is it?

Interestingly enough, if we think about using == or != it becomes apparent very quickly using these operators is not the proper way to check if a variable is null or not because, in C#, we have operator overloading. See the following example:

public class Car
{
    public static bool operator ==(Car lhs, Car rhs) => true;

    public static bool operator !=(Car lhs, Car rhs) => !(lhs == rhs);
}
Enter fullscreen mode Exit fullscreen mode

For this implementation we will have inappropriate results for null checking as demonstrated below:

[Fact]
public void CSharp_Runtime_Should_Return_True_Provided_That_Variable_Is_Not_Null()
{
    var car = new Car();
   (car == null).ShouldBeTrue();
}

[Fact]
public void CSharp_Runtime_Should_Return_False_Provided_That_Variable_Is_Not_Null()
{
    var car = new Car();
   (car != null).ShouldBeFalse();
}
Enter fullscreen mode Exit fullscreen mode

Then what's the solution?

Use is & is not operator combination as shown below:

[Fact]
public void CSharp_Runtime_Should_Return_False_Provided_That_Variable_Is_Not_Null()
{
    var car = new Car();
    (car is null).ShouldBeFalse();
}

[Fact]
public void CSharp_Runtime_Should_Return_True_Provided_That_Variable_Is_Not_Null()
{
    var car = new Car();
    (car is not null).ShouldBeTrue();
}
Enter fullscreen mode Exit fullscreen mode

Use is { } expression as below:

[Fact]
public void CSharp_Runtime_Should_Return_True_That_Variable_Is_Not_Null_Using_Property_Pattern_Matching()
{
    var car = new Car();
    (car is { }).ShouldBeTrue();
}

[Fact]
public void CSharp_Runtime_Should_Return_False_That_Variable_Is_Null_Using_Property_Pattern_Matching()
{
    Car car = null;
    (car is { }).ShouldBeFalse();
}
Enter fullscreen mode Exit fullscreen mode

Note: is { } expression checks if the variable is an instance of object

Use object.ReferenceEquals static method as below:

[Fact]
public void CSharp_Runtime_Should_Return_True_Provided_That_Variable_Is_Not_Null_Using_Reference_Equality_Check()
{
    var car = new Car();
    car.IsNotNull().ShouldBeTrue();
}

[Fact]
public void CSharp_Runtime_Should_Return_False_Provided_That_Variable_Is_Null_Using_Reference_Equality_Check()
{
    Car car = null;
    car.IsNotNull().ShouldBeFalse();
}

...
...
...

public static class ObjectExtensions
{
    public static bool IsNull<T>(this T obj) => ReferenceEquals(obj, null);

    public static bool IsNotNull<T>(this T obj) => !obj.IsNull();
}
Enter fullscreen mode Exit fullscreen mode

Post inspiration: How null checks have changed in C#

Discussion (1)

pic
Editor guide
Collapse
parajdox profile image
John Dave Dalmao • Edited

When I use the "is" to check for null it works, but when I use "is not", I get this error: "Feature "not pattern" is not available in C#8.0. Please use language 9.0 or greater"

//check the image for my versions... my vs2019 is up to date, and I don't know where to change the version (if I needed to)

dev-to-uploads.s3.amazonaws.com/up...