Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有标准类来表示“;范围”;在.net中?_.net_Design Patterns_Range - Fatal编程技术网

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

是否有标准类来表示“;范围”;在.net中?,.net,design-patterns,range,.net,Design Patterns,Range,我们有很多代码,对于价格、利润、成本等具有“min”和“max”值。目前,它们作为两个参数传递给方法,并且通常具有不同的属性/方法来检索它们 在过去的几十年里,我已经看到了101个自定义类,它们在不同的代码库中存储不同的值范围。在我创建另一个这样的类之前,我想确认一下,现在的.NET framework没有内置这样的类 (如果需要的话,我知道如何创建自己的类,但是这个世界上已经有太多的轮子了,我无法一时兴起再发明一个)没错,在2020年之前,C#或BCL for ranges中没有内置类。但是,

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

在过去的几十年里,我已经看到了101个自定义类,它们在不同的代码库中存储不同的值范围。在我创建另一个这样的类之前,我想确认一下,现在的.NET framework没有内置这样的类


(如果需要的话,我知道如何创建自己的类,但是这个世界上已经有太多的轮子了,我无法一时兴起再发明一个)

没错,在2020年之前,C#或BCL for ranges中没有内置类。但是,BCL中有表示时间跨度的
TimeSpan
,您还可以用
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;
    }
}
公共枚举范围边界类型
{
包含=0,
独家
}
公共结构范围:IComparable、IEquatable
其中T:struct,i可比较
{
公共范围(T最小值,T最大值):
此(最小值,RangeBoundaryType.Inclusive,
最大值,范围边界类型(包括)
{
}
公共范围(T最小值,范围边界类型最小边界,
T最大值,范围边界类型(最大边界)
{
这个.Min=Min;
这个。Max=Max;
this.MinBoundary=MinBoundary;
this.MaxBoundary=MaxBoundary;
}
公共T Min{get;私有集;}
公共T Max{get;私有集;}
public RangeBoundaryType MinBoundary{get;private set;}
public RangeBoundaryType MaxBoundary{get;private set;}
公共布尔包含(范围其他)
{
//待办事项
}
公共布尔重叠开关(范围其他)
{
//待办事项
}
公共重写字符串ToString()
{
返回string.Format(“Min:{0}{1},Max:{2}{3}”,
this.Min,this.MinBoundary,this.Max,this.MaxBoundary);
}
公共覆盖int GetHashCode()
{

返回这个.Min.GetHashCode()我已经开始自己做了

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);
    }
}
公共类范围,其中T:i可比较
{
私有只读存储器不能启动;
专用只读T端;
公共范围(T开始,T结束)
{
如果(开始比较到(结束)<0)
{
this.start=start;
this.end=end;
}
其他的
{
this.start=end;
this.end=开始;
}
}
公共交通不能启动
{
得到
{
返回此文件。开始;
}
}
公共T端
{
得到
{
把这个还给我。结束;
}
}
公共静态布尔交叉点(范围a、范围b)
{
返回!(b.Start.CompareTo(a.End)>0 | | a.Start.CompareTo(b.End)>0);
}
公共布尔交叉点(范围其他)
{
返回相交(此,其他);
}
}

这一点刚刚在.Net Core 3.0中有所改变,请参见。
C#8也有

另请参见“”Stackoverflow问题


注意这些只支持整数的范围,不支持双精度或浮点的范围。

我没有否决你的意见,但我不喜欢在这里强制t为struct?为什么这样的约束?另一件事是范围本身不应该是struct。struct占用的内存比指针少时是好的(那么它是高效的——复制)。这个类显然需要超过4或8个字节。@dzendras:我同意你的意见。这个想法是为了给类型-值-类型语义,所以我选择了
struct
,但这不是必须的。请注意,框架设计指南建议值类型小于16个字节,所以不是8或4,但范围很容易变成16 b例如,当使用
范围时,我也得到了两张无法解释的否决票。相当恼人。我想是因为.Net实际上有一个,它是System.Core dll中的可枚举类,所以它是内置的,并且有一些范围API。@Jason,FCL中的那个只是一个数字范围,但它在那里,非常适合我们当你需要一些基本的范围来构建你自己的东西时,这是非常有用的。我在猜测为什么回复得到了一些反对票。但是,老实说,不是我。我只是在猜测。@Jason。是的,是的。请看@sovemp:No,这是为了在给定范围内生成序列,这与让你测试成员资格的ADT范围不同,等等。