namespace domain { using System; using utility; public static class Ranges { public static IRange UpTo(this T start, T end) where T: IComparable, IIncrementable { return new Range(start, end); } } public interface IRange : IVisitable where T : IComparable { void Accept(Action action); bool Contains(T item); } public class Range : IRange where T : IComparable, IIncrementable { T start; T end; public Range(T start, T end) { this.start = start; this.end = end; } public void Accept(IVisitor visitor) { Accept(visitor.Visit); } public void Accept(Action visitor) { var next = this.start; var last = this.end.Next(); while(!next.Equals(last)) { visitor(next); next = next.Next(); } } public bool Contains(T item) { return start.CompareTo(item) <= 0 && end.CompareTo(item) > 0; } } public interface IIncrementable { T Next(); } }