Implementing a binary operation for the null object pattern Today I needed to implement a class for representing rectangular regions with some binary operations such as merging or intersection.

public class Region
{
    // Properties, such as top-left and bottom-right corner ...
    // Ctors ...

    public Region Merge(Region other)
    {
        // ...
    }

    public Region Insersect(Region other)
    {
        // ...
    }
}


Intersecting two instances of Region unfortunately does not always have a useful result. So my next step was to implement the notion of a NullRegion. It is no problem to implement the NullRegion itself. However, this would require Region to check against NullRegion, as those binary operations are commutative and the order should not matter. (i.e. nullRegion.Intersect(nonNullRegion)should yield the same result as nonNullRegion.Intersect(nullRegion), which is a NullRegion)

The first solution I can think of is to move the implementation of those methods into a seperate class. That way, I only the new class needs to know the NullRegion.

public class Region
{
    // Properties, such as top-left and bottom-right corner ...
    // Ctors ...

    public virtual bool IsNull { get { return false; } }

    public Region Merge(Region other)
    {
        return RegionMethods.Merge(this, other);
    }

    public Region Intersect(Region other)
    {
        return RegionMethods.Intersect(this, other);
    }

    private class NullRegion
    {
        public override bool IsNull { get { return true; } }
    }

    private static class RegionMethods
    {
        public static Region Merge(Region Region, Region otherRegion)
        {
            // ...
        }

        public static Region Intersect(Region Region, Region otherRegion)
        {
            // ...
        }
    }
}


Is this a good way to tackle the problem? What would be my alternatives?
The implementation of a NullRegion, shouldn't be done by a separate class, but by a static property of the same class.
If you overide Equals() and GetHashCode() you can just compare the objects to Region.NullRegion like  

public class Region
{
    private static readonly Region nullRegion = new Region();

    private Region()
    {
        Left = 0;
        Top = 0;
        Width = 0;
        Height = 0;
    }
    public Region(Point point, Size size)
    {
        Left = point.X;
        Top = point.Y;
        Width = size.Width;
        Height = size.Height;
    }
    public static Region NullRegion
    {
        get
        {
            return nullRegion;
        }

    }
    public int Left { get; set; }
    public int Top { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }

    public Region Merge(Region other)
    {
        if (this == Region.NullRegion || other == Region.NullRegion)
        {
            return Region.NullRegion;
        }
        // default Merge() implementation here
    }
    public Region Intersects(Region other)
    {
        if (this == Region.NullRegion || other == Region.NullRegion)
        {
            return Region.NullRegion;
        }
        // default Intersects() implementation here

    }
    public override bool Equals(object obj)
    {
        //Implementation of your Equals() here
        return base.Equals(obj);
    }
    public override int GetHashCode()
    {
        //Implementation of your GetHashCode() here
        return base.GetHashCode();
    }
}