It has taken awhile, but I have finally started on a C# project using VS2005. For the moment, VB6 has been retired.
My initial actions have been porting some utility classes forward to a new library. One of the first ones I tackled is a generic range class to support the many ranges the project will be tracking. Things went well until I got to the part about defining the interaction while comparing two generic ranges. My current (partial) definition is:
public class Range : IRange where T : IComparable
{
public Range(T start, T end)
// These Methods compare a Range and a single value
public bool Contains(T value)
public bool Omits(T value)
public bool IsBefore(T value)
public bool IsAfter(T value)
// These Methods compare two Ranges
public bool Equals(Range<T> range)
public bool Equals(Range<T> range1, Range<T> range2)
public bool IsBefore(Range<T> range)
public bool IsAfter(Range<T> range)
public bool IsSubsetOf(Range<T> range)
public bool IsSupersetOf(Range<T> range)
public bool IsContainedIn(Range<T> range)
public bool IsOmittedFrom(Range<T> range)
public bool Overlaps(Range<T> range)
public bool OverlapsStart(Range<T> range)
public bool OverlapsEnd(Range<T> range)
...
}
Now my problem is one of usage. I am not happy with my naming scheme There are six possible cases involving the way ranges can overlap (or not). I wanted simple tests from a usage point of view, but naming things such that it reads much like an English sentence seems counterintuitive.
IRange<decimal> myRange = new Range<decimal>(50, 80);
IRange<decimal> testRange1 = new Range<decimal>(20, 40);
IRange<decimal> testRange2 = new Range<decimal>(40, 60);
IRange<decimal> testRange3 = new Range<decimal>(60, 70);
IRange<decimal> testRange4 = new Range<decimal>(70, 90);
IRange<decimal> testRange5 = new Range<decimal>(90, 100);
IRange<decimal> testRange6 = new Range<decimal>(40, 90);
// All results are true
result = myRange.Contains(60);
result = myRange.Omits(30);
result = myRange.IsBefore(30);
result = myRange.IsAfter(90);
result = myRange.IsAfter(testRange1);
result = myRange.OverlapsEnd(testRange2);
result = myRange.IsSupersetOf(testRange3);
result = myRange.OverlapsStart(testRange4);
result = myRange.IsBefore(testRange5);
result = myRange.IsSubsetOf(testRange6);
This seems wrong. I have not seen other examples of this type of class, but I think I should invert the processing logic. Anyone have any thoughts or examples?