2012-04-16 14 views
5

私たちは、価格、利益、費用などのために "最小値"と "最大値"を持つコードをたくさん持っています。現在、これらは2つのパラメータとしてメソッドに渡されています。.netに "範囲"を表す標準クラスはありますか?

これまでの数十年にわたりさまざまなコードベースに値の範囲を格納するためのカスタムクラスが101個ありました。これらのクラスを作成する前に、クラスに組み込まれています。

(私は必要に応じて自分のクラスを作成する方法を知っているが、私はただ気まぐれに葯1を発明するために、我々はすでにこの世界であまりにも多くの車輪を持っている)

答えて

5

正しいのです。つまり、そこには何も構築されていません範囲のC#またはBCLのクラス。ただし、時間範囲を表すBCLにはTimeSpanがあります。これは、範囲を表すためにDateTimeでさらに構成できます。

+1

なぜこれがダウンリストされましたか? – jason

+0

これについてのdownvotesは私を混乱させています。 – jason

+0

私は2つの説明できないdownvotesも得ました。かなり迷惑な。補償するために私から+ 1。 – Steven

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

downvotersはdownvoteを説明できますか? – Steven

+0

私はあなたに落とし込んだことはありませんが、私がここで好きではないことは、Tが構造体であることを強制していますか?なぜそのような制約?もう一つは、範囲自体が構造体ではないということです。構造体がポインタよりも少ないメモリを占有しているときは良いです(効率的です - コピーする)。このクラスは明らかに4バイトまたは8バイト以上必要です。 – dzendras

+0

@dzendras:私はあなたのコメントに同意します。アイデアは、型の値型セマンティクスを与えることでしたので、私は 'struct'を選んだが、これは必ずしも必要ではありません。フレームワーク設計ガイドラインでは、値の型は16バイトよりも小さいので、8または4ではなく、Rangeが容易に16バイト以上になることに注意してください。たとえば、 'Range 'を使用する場合です。 – Steven

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); 
    } 
} 
関連する問題