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
}
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);
}
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();
}
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();
}
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();
}
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();
}
Post inspiration: How null checks have changed in C#
Top comments (1)
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...