patterncsharpMinor
Implementing a binary operation for the null object pattern
Viewed 0 times
thenulloperationbinaryforobjectimplementingpattern
Problem
Today I needed to implement a class for representing rectangular regions with some binary operations such as merging or intersection.
Intersecting two instances of
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
Is this a good way to tackle the problem? What would be my alternatives?
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?
Solution
The implementation of a
If you overide
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();
}
}Code Snippets
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();
}
}Context
StackExchange Code Review Q#71975, answer score: 3
Revisions (0)
No revisions yet.