Richard Deeming
Вот немного более полная универсальная реализация:
public struct Range<T> : IEquatable<Range<T>>
{
public Range(T minimum, T maximum, IComparer<T> comparer = null)
{
if (minimum == null) throw new ArgumentNullException(nameof(minimum));
if (maximum == null) throw new ArgumentNullException(nameof(maximum));
if (comparer == null) comparer = Comparer<T>.Default;
if (comparer.Compare(minimum, maximum) <= 0)
{
Minimum = minimum;
Maximum = maximum;
}
else
{
Minimum = maximum;
Maximum = minimum;
}
}
public Range(T value)
{
if (value == null) throw new ArgumentNullException(nameof(value));
Minimum = value;
Maximum = value;
}
public T Minimum { get; }
public T Maximum { get; }
public override string ToString()
{
return $"Range[{Minimum},{Maximum}]";
}
public override int GetHashCode()
{
unchecked
{
return (Minimum.GetHashCode() * 397) ^ Maximum.GetHashCode();
}
}
public override bool Equals(object obj)
{
return obj is Range<T> && Equals((Range<T>)obj);
}
public bool Equals(Range<T> other)
{
var comparer = EqualityComparer<T>.Default;
return comparer.Equals(Minimum, other.Minimum)
&& comparer.Equals(Maximum, other.Maximum);
}
public static bool operator ==(Range<T> left, Range<T> right)
{
return left.Equals(right);
}
public static bool operator !=(Range<T> left, Range<T> right)
{
return !left.Equals(right);
}
public bool Contains(T value, IComparer<T> comparer = null)
{
if (comparer == null) comparer = Comparer<T>.Default;
return comparer.Compare(Minimum, value) <= 0
&& comparer.Compare(value, Maximum) <= 0;
}
public bool Contains(Range<T> range, IComparer<T> comparer = null)
{
if (comparer == null) comparer = Comparer<T>.Default;
return comparer.Compare(Minimum, range.Minimum) <= 0
&& comparer.Compare(range.Maximum, Maximum) <= 0;
}
public bool Overlaps(Range<T> range, IComparer<T> comparer = null)
{
if (comparer == null) comparer = Comparer<T>.Default;
return comparer.Compare(Minimum, range.Maximum) <= 0
&& comparer.Compare(range.Minimum, Maximum) <= 0;
}
}