Skip to content

Instantly share code, notes, and snippets.

@mike-kilo
Created March 23, 2021 10:04
Show Gist options
  • Save mike-kilo/18ea3e997cf74c7a7945d82e2d530972 to your computer and use it in GitHub Desktop.
Save mike-kilo/18ea3e997cf74c7a7945d82e2d530972 to your computer and use it in GitHub Desktop.
Range
using System;
using System.Collections.Generic;
using System.Linq;
namespace Helpers
{
public struct Range<T> where T : IComparable
{
public T Start { get; set; }
public T End { get; set; }
private T GetMeasure()
{
try
{
return (T)Math.Abs((dynamic)this.End - (dynamic)this.Start);
}
catch (Exception e)
{
throw new TypeAccessException($"'Range' struct of type '{typeof(T).FullName}' does not support range measure.", e);
}
}
/// <summary>
/// The measure of the range, including the starting limit.
/// </summary>
/// <remarks>
/// E.g. if the range is [3; 7], the Measure is 4
/// </remarks>
public T Measure
{
get
{
return this.GetMeasure();
}
}
public bool Contains(T value)
{
try
{
return (dynamic)value >= (dynamic)this.Start && (dynamic)value <= (dynamic)this.End;
}
catch (Exception e)
{
throw new TypeAccessException($"'Range' struct of type '{typeof(T).FullName}' does not support value comparison.", e);
}
}
public static Range<T> operator* (Range<T> multiplier, T multiplicant)
{
try
{
return new Range<T> { Start = (dynamic)multiplier.Start * (dynamic)multiplicant, End = (dynamic)multiplier.End * (dynamic)multiplicant };
}
catch (Exception e)
{
throw new TypeAccessException($"'Range' struct of type '{typeof(T).FullName}' does not support multiplication.", e);
}
}
public static Range<T> operator /(Range<T> divident, T divisor)
{
if ((dynamic)divisor == 0.0) throw new ArgumentException("Divide by zero? Please...");
try
{
return new Range<T> { Start = (dynamic)divident.Start / (dynamic)divisor, End = (dynamic)divident.End / (dynamic)divisor };
}
catch (Exception e)
{
throw new TypeAccessException($"'Range' struct of type '{typeof(T).FullName}' does not support division.", e);
}
}
public static Range<T> operator +(Range<T> summand1, T summand2)
{
try
{
return new Range<T> { Start = (dynamic)summand1.Start + (dynamic)summand2, End = (dynamic)summand1.End + (dynamic)summand2 };
}
catch (Exception e)
{
throw new TypeAccessException($"'Range' struct of type '{typeof(T).FullName}' does not support addition or the sum is outside of the range of '{typeof(T).FullName}'.", e);
}
}
public static Range<T> operator -(Range<T> minuend, T subtrahend)
{
try
{
return new Range<T> { Start = (dynamic)minuend.Start - (dynamic)subtrahend, End = (dynamic)minuend.End - (dynamic)subtrahend };
}
catch (Exception e)
{
throw new TypeAccessException($"'Range' struct of type '{typeof(T).FullName}' does not support subtraction or the difference is outside of the range of '{typeof(T).FullName}'.", e);
}
}
public static explicit operator Range<int>(Range<T> v)
{
try
{
return new Range<int> { Start = (int)(dynamic)v.Start, End = (int)(dynamic)v.End };
}
catch (Exception e)
{
throw new TypeAccessException($"'Range' struct of type '{typeof(T).FullName}' does not support casting to int.", e);
}
}
public static explicit operator Range<double>(Range<T> v)
{
try
{
return new Range<double> { Start = (double)(dynamic)v.Start, End = (double)(dynamic)v.End };
}
catch (Exception e)
{
throw new TypeAccessException($"'Range' struct of type '{typeof(T).FullName}' does not support casting to double.", e);
}
}
public static Range<T> Average(IEnumerable<Range<T>> ranges)
{
try
{
return ranges.Aggregate((a, b) => new Range<T> { Start = (dynamic)a.Start + (dynamic)b.Start, End = (dynamic)a.End + (dynamic)b.End }) / (dynamic)ranges.Count();
}
catch (Exception e)
{
throw new TypeAccessException($"'Range' struct of type '{typeof(T).FullName}' does not support averaging.", e);
}
}
public override bool Equals(object obj)
{
return (obj is Range<T>) &&
this.Start.Equals(((Range<T>)obj).Start) &&
this.End.Equals(((Range<T>)obj).End);
}
public override int GetHashCode()
{
return this.Start.GetHashCode() ^ this.End.GetHashCode();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment