Tuesday, February 24, 2015

Null Object Pattern in C#

Instead of using a null reference to convey absence of an object (for instance, a non-existent customer), one uses an object which implements the expected interface, but whose method body is empty. The advantage of this approach over a working default implementation is that a Null Object is very predictable and has no side effects: it does nothing.

For example, a function may retrieve a list of files in a folder and perform some action on each. In the case of an empty folder, one response may be to throw an exception or return a null reference rather than a list. Thus, the code which expects a list must verify that it in fact has one before continuing, which can complicate the design.

By returning a null object (i.e. an empty list) instead, there is no need to verify that the return value is in fact a list. The calling function may simply iterate the list as normal, effectively doing nothing. It is, however, still possible to check whether the return value is a null object (e.g. an empty list) and react differently if desired.

The null object pattern can also be used to act as a stub for testing, if a certain feature such as a database is not available for testing.



C# is a language in which the Null Object pattern can be properly implemented. This example shows animal objects that display sounds and a NullAnimal instance used in place of the C# null keyword. The Null Object provides consistent behaviour and prevents a runtime Null Reference Exception that would occur if the C# null keyword were used instead.

using System;

static class Program
{
    static void Main()
    {
        IAnimal dog = new Dog();
        dog.MakeSound(); // outputs "Woof!"

        /* Instead of using C# null, use a NullAnimal instance.
         * This example is simplistic but conveys the idea that if a NullAnimal instance is used then the program
         * will never experience a .NET System.NullReferenceException at runtime, unlike if C# null was used.
         */
        IAnimal unknown = new NullAnimal();  //<< replaces: IAnimal unknown = null;
        unknown.MakeSound(); // outputs nothing, but does not throw a runtime exception      
    }
}

// Animal interface is the key to compatibility for Animal implementations below.
interface IAnimal
{
    void MakeSound();
}

// Dog is a real animal.
class Dog : IAnimal
{
    public void MakeSound()
    {
        Console.WriteLine("Woof!");
    }
}

// The Null Case: this NullAnimal class should be instantiated and used in place of C# null keyword.
class NullAnimal : IAnimal
{
    public void MakeSound()
    {
        // Purposefully provides no behaviour.
    }
}
More information about Null Object Pattern can be found on http://en.wikipedia.org/wiki/Null_Object_pattern#C.23
and also on http://www.cs.oberlin.edu/~jwalker/nullObjPattern/

No comments:

Post a Comment