The Null Object Pattern is a behavioral design pattern that provides an object to stand in for the missing object in an interface. It's a way to offer an alternate action in situations when a null object would raise a null reference exception. In this post, we'll go deeply into the C# Null Object Pattern and gradually advance to more complicated scenarios.

The Pattern of Null Object Design What's that?
The use of the Null object pattern is one design strategy that facilitates the use of potentially undefined dependencies. This is done by using instances of a concrete class that implements a recognized interface in place of null references. Together with concrete classes that extend it and a null object class that provides a do-nothing version of the class that can be used anyplace we need to verify the null value, an abstract class detailing the various actions to be performed is constructed.

The Null Object Design Pattern's constituent parts
Customer

The client is the code that depends on an object that either implements a Dependency interface or extends an abstract DependencyBase class. The client uses this item to complete a task. The client shouldn't need to know which kind of object it is working with in order to handle both real and null objects in the same manner.

DependencyBase or Abstract Dependency
An abstract class or interface called DependencyBase specifies the methods that must be implemented by all concrete dependents, including the null object. The contract that all dependencies have to abide by is defined by this class.

Dependency or Real Dependency

The Client may utilize this class as a functional dependency. It is not necessary for the client to know if Dependency objects are actual or null in order to interact with them.

NullObject or Null Dependency
This is the class of null objects that the client may utilize as a dependency. While it implements every member specified by the DependencyBase abstract class, it lacks functionality. A null or non-existent dependency in the system is represented by a NullObject. Methods on a NullObject can be securely called by the client without resulting in errors or requiring null checks.

As an illustration,
Abstract Dependency

Here is the code for the ICar.cs file.
public interface ICar
{
    void Drive();

    void Stop();
}

Real Dependency
Here is the code for the SedanCar.cs file.
public class SedanCar : ICar
{
    public void Drive()
    {
        Console.WriteLine("Drive the sedan car.");
    }

    public void Stop()
    {
        Console.WriteLine("Stop the sedan car.");
    }
}

Null Object Dependency
Here is the code for the NullCar.cs file.
public class NullCar : ICar
{
    public void Drive()
    {

    }

    public void Stop()
    {

    }
}

Client

Here is the code for the CarService.cs file.
public class CarService(ICar car)
{
    private readonly ICar _car = car;

    public void Run()
    {
        Console.WriteLine($"Start run method. {nameof(ICar)}: {_car}");
        _car.Drive();
        _car.Stop();

        Console.WriteLine($"Complete run method. {nameof(ICar)}: {_car}");
        Console.WriteLine();
    }
}


Program
Here is the code for the Program.cs file.
var sedanCar = new SedanCar();
var carService = new CarService(sedanCar);

carService.Run();

var nullCar = new NullCar();
carService = new CarService(nullCar);

carService.Run();

Output

When to apply the Design Pattern for Null Objects?
When you want to provide a default or no-op implementation of an object's functionality to avoid null checks and handle null references gracefully, you can use the Null Object Design Pattern. The following situations call for the application of the Null Object Design Pattern.

  • Default Behavior: This is the behavior you want to give an object in the event that its real implementation is unavailable or inappropriate.
  • Avoid Null Checks: When you want to provide a null object implementation that may be used safely in place of a null reference, you can avoid having to do explicit null checks in your code.
  • Consistent Interface: In situations when you need to give customers access to an interface that stays the same whether they are working with real or null objects.
  • Simplifying Client Code: When you wish to spare client code from handling null references by letting them handle null objects in the same manner as actual objects.

When the Null Object Design Pattern should not be used?
The Null Object Design Pattern might not be appropriate in the following situations.

  • Sophisticated Behavior: The Null Object Design Pattern is meant to provide simple default behavior; therefore, it might not be acceptable when the null object needs to implement sophisticated behavior or store state.
  • Performance Considerations: It could be preferable to handle null references directly in the code if generating and utilizing null objects significantly increases overhead or complexity in the system.
  • Confusion with Real Objects: Explicit null checks may be preferable in order to improve the readability and clarity of the code if there is a chance that null objects and real objects could be confused in the system.

Summary
A solid method for handling the lack of objects is provided by the Null Object Pattern, a design pattern. It lowers the possibility of runtime mistakes and simplifies client code by offering a default behavior and doing away with the necessity for null checks. To improve stability and maintainability, the Null Object Pattern can be a useful tool when building a new system or restructuring an old one.

We learned the new technique and evolved together.

HostForLIFE ASP.NET Core 9.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.