我们有很多代码,其中包含价格、利润、成本等的“最小值”和“最大值”。目前,它们作为两个参数传递给方法,并且通常具有不同的属性/方法来检索它们。
在过去的几十年里,我已经看到了 101 个自定义类来存储不同代码库中的值范围,在我创建另一个这样的类之前,我希望确认现在的 .NET 框架没有内置这样的类某处。
(如果需要,我知道如何创建自己的课程,但我们已经有太多的轮子了,我无法一时兴起发明另一个)
我们有很多代码,其中包含价格、利润、成本等的“最小值”和“最大值”。目前,它们作为两个参数传递给方法,并且通常具有不同的属性/方法来检索它们。
在过去的几十年里,我已经看到了 101 个自定义类来存储不同代码库中的值范围,在我创建另一个这样的类之前,我希望确认现在的 .NET 框架没有内置这样的类某处。
(如果需要,我知道如何创建自己的课程,但我们已经有太多的轮子了,我无法一时兴起发明另一个)
没错,在 2020 年之前,C# 或范围的 BCL 中没有内置类。但是,TimeSpan
BCL 中有用于表示时间跨度的内容,您可以另外使用 a 组合DateTime
来表示时间范围。
AFAIK .NET 中没有这样的东西。不过,想出一个通用的实现会很有趣。
构建一个通用的 BCL 质量范围类型需要做很多工作,但它可能看起来像这样:
public enum RangeBoundaryType
{
Inclusive = 0,
Exclusive
}
public struct Range<T> : IComparable<Range<T>>, IEquatable<Range<T>>
where T : struct, IComparable<T>
{
public Range(T min, T max) :
this(min, RangeBoundaryType.Inclusive,
max, RangeBoundaryType.Inclusive)
{
}
public Range(T min, RangeBoundaryType minBoundary,
T max, RangeBoundaryType maxBoundary)
{
this.Min = min;
this.Max = max;
this.MinBoundary = minBoundary;
this.MaxBoundary = maxBoundary;
}
public T Min { get; private set; }
public T Max { get; private set; }
public RangeBoundaryType MinBoundary { get; private set; }
public RangeBoundaryType MaxBoundary { get; private set; }
public bool Contains(Range<T> other)
{
// TODO
}
public bool OverlapsWith(Range<T> other)
{
// TODO
}
public override string ToString()
{
return string.Format("Min: {0} {1}, Max: {2} {3}",
this.Min, this.MinBoundary, this.Max, this.MaxBoundary);
}
public override int GetHashCode()
{
return this.Min.GetHashCode() << 256 ^ this.Max.GetHashCode();
}
public bool Equals(Range<T> other)
{
return
this.Min.CompareTo(other.Min) == 0 &&
this.Max.CompareTo(other.Max) == 0 &&
this.MinBoundary == other.MinBoundary &&
this.MaxBoundary == other.MaxBoundary;
}
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 int CompareTo(Range<T> other)
{
if (this.Min.CompareTo(other.Min) != 0)
{
return this.Min.CompareTo(other.Min);
}
if (this.Max.CompareTo(other.Max) != 0)
{
this.Max.CompareTo(other.Max);
}
if (this.MinBoundary != other.MinBoundary)
{
return this.MinBoundary.CompareTo(other.Min);
}
if (this.MaxBoundary != other.MaxBoundary)
{
return this.MaxBoundary.CompareTo(other.MaxBoundary);
}
return 0;
}
}
我已经开始自己制作了。
public class Range<T> where T : IComparable
{
private readonly T start;
private readonly T end;
public Range(T start, T end)
{
if (start.CompareTo(end) < 0)
{
this.start = start;
this.end = end;
}
else
{
this.start = end;
this.end = start;
}
}
public T Start
{
get
{
return this.start;
}
}
public T End
{
get
{
return this.end;
}
}
public static bool Intersect(Range<T> a, Range<T> b)
{
return !(b.Start.CompareTo(a.End) > 0 || a.Start.CompareTo(b.End) > 0);
}
public bool Intersect(Range<T> other)
{
return Intersect(this, other);
}
}
.Net Core 3.0 改变了这一点,请参见System.Range。
C# 8 还具有创建范围的语言支持。
另请参阅“什么是 c# 8 中的范围和索引类型? ” Stackoverflow 问题。
请注意,这些仅支持整数范围,不支持双精度或浮点范围。