是否有标准类来表示.net中的“范围”?

时间:2012-04-16 10:56:08

标签: .net design-patterns range

我们有很多代码,其中包含价格,利润,成本等“min”和“max”值。目前,这些代码作为两个参数传递给方法,并且通常具有不同的属性/方法来检索它们。 / p>

在我创建另一个这样的类之前,我已经看到了101个自定义类来存储不同代码库中的值范围,我希望确认.NET框架现在没有这样的内置类。

(我知道如果需要的话,如何创建我自己的课程,但是我已经在这个世界上有太多的轮子让我只是随心所欲地发明一个)

4 个答案:

答案 0 :(得分:6)

这是正确的,C#中没有内置类,范围内没有BCL。但是,BCL中有TimeSpan表示时间跨度,您可以使用DateTime进行组合以表示时间范围。

答案 1 :(得分:6)

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;
    }
}

答案 2 :(得分:1)

我已经开始自己做了。

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);
    }
}

答案 3 :(得分:1)

.NET 4.6.1对此进行了更改,请参见System.Range
C#8也有language support for creating ranges

另请参阅“ What is Range and Index types in c# 8?” Stackoverflow问题。

请注意,这些仅支持整数范围,不支持double或float范围。