2009-12-04 31 views
47

私のドメインオブジェクトの数は、開始日と終了日のプロパティのペアとして日付範囲含まれていますDateRangeオブジェクトを作成する必要がありますか?

public class Period { 
    public DateTime EffectiveDate { get; set; } 
    public DateTime ThroughDate { get; set; } 
} 

public class Timeline { 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; } 
} 

をそして私はこのたくさんのと自分自身を見つける:最後の私を作っ

abstract public int Foo(DateTime startDate, DateTime endDate); 
abstract public decimal Bar(DateTime startDate, DateTime endDate); 
abstract public ICollection<C5.Rec<DateTime, DateTime>> FooBar(DateTime startDate, DateTime endDate); 

wonder ...私はDateRangeクラスを実装する必要がありますか?私はBCLの1つを認識していません。

私の経験では、オブジェクト階層を深くすると、事態が複雑になることがよくあります。これらのオブジェクトは、ReportViewerコントロールによって表示されるRDLCレポートに送信されますが、それはセカンダリです。モデルのビューを曲げるのではなく、モデルのビューを曲げます。我々は、しかし、プロパティ名に関連付けられていない、とのようなもので妥協して喜んで次のようになります。開始日後に来て終了日の

public class DateRange { 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; } 
} 

Period p = new Period(); 
DateTime t = p.EffectiveDateRange.StartDate; 

のDateRangeクラスの利益が集中されるだろう、検証、および

私は、DateRangeクラスが私の価値よりも苦労することはないと確信しています。意見ですか?

サイド質問:BCLの一般的な汎用タプルクラスをどこかで見逃しましたか?私はいくつかの非常に特定のものがさまざまな名前空間に浮かんでいることを知っています。私のパブリックドメインメソッドシグニチャーをC5タイプで汚染すると、非常に汚れているように感じます。

+0

私は間違いなく、DateRangeクラスが役立つと思います。私はしばらく前に土台を書くようになった:http://www.adamjamesnaylor.com/2012/11/04/C-DateRange-Class.aspx –

+0

@AdamNaylor:あなたのリンクはダウンしているようだ... – testing

答えて

33

いいえ、あなたは汎用クラスを見逃していませんでした。

私はMiscUtilRangeタイプを持っています。これは簡単にDateTimeの操作になります。 Marcの答えを参照して、私はこれが構造体かクラスかを覚えていません - あなたはもちろんそれを変更することを歓迎します。

Marcのジェネリックスのためにうまくやり抜くのは簡単です(.NET 3.5を使用していると仮定すると、少なくとも2で実現可能です)。0現在のところサポートされていません)。

Range<DateTime> range = 19.June(1976).To(DateTime.Today); 

foreach (DateTime date in range.Step(1.Days()) 
{ 
    // I was alive in this day 
} 

(それはまた、拡張メソッドの束を使用しています - 生産よりもテストのために、より便利。)

をマルクの答えの他の点に対処するために、Noda Timeは確かに日付の概念を表現することができるようになります.NET APIよりも適切ですが、現時点では範囲のようなものはありません...しかし、私はfeature requestを追加しました。

+0

申し訳ありませんが、ノーダタイムについて誤って話しました。 –

+0

いいえ、それはいいですね - あなたがそれを言及していなかったなら、私はプロジェクトに機能要求を追加することを考えていたかどうかはわかりません:)私はそれがかなり共通の要件だと思う - トリッキーなビットがうまくいくでしょう人々が望む多様な調整に対応するために必要なもの! –

+9

興味深い構文です。 –

5

日付を使用して多くの作業を行う場合、はい - 範囲が便利です。これは実際にはあなたがの場合はと書いてありますが、それはおそらくstruct(不変)と書いてあります。しかし、「野田の時間」は、おそらくこれ以上のことをあなたに与えるでしょう(完了したら)。私は前にスケジューリングソフトウェアをやった。私はそのような構造体をいくつか持っていました(わずかに異なる仕事のために)。

このため、便利なBCL構成はありません。

また、あなたが範囲を持っているときに集中化できるすばらしいメソッド(と演算子)を考えてみましょう。 (他の範囲の日時の、制限を含む/除外する)、「交差する」、オフセット - バイパス(タイムスパン)などを含めることができる。確定型ケースを処理するためのケース。 ORMレベルでは、ORMが複合値をサポートしていれば、これは簡単です - 私はNHibernateは、おそらくEF 4.0と考えています。

+0

ああ、はい、野田。それを待っている.... –

+0

これは、より良い日付と範囲の操作を処理するためのリファクタリングであることを考えれば、私はそれをクラスに与える意味があると思います。 私はこのプロジェクトでNHibernateを使用したかっただけです。私は自分自身だと言うとかなり時間がかかりましたが、比較では薄かったです。しかし、次のプロジェクト。私はそれをつかむために今遊んでいます。 –

0

私は、DateRange性質のネイティブ.NETクラスについて知らない。最も近いものはおそらくDateTime + TimeSpanまたはDateTime/DateTimeの組み合わせです。

私はあなたが望むものはかなり健全だと思います。

0

MarkとJonがすでに言及しているように、私はこれを値型として作成しますが、これは不変です。私はそれを構造体として実装し、IEquatableとIComparableインタフェースを実装することを選択します。

NHibernateのようなORMを使用すると、エンティティを表すテーブルの中に値の型を格納することができます。

+0

したがって、DateRangeサブオブジェクトを持つのは難しいことではなく、NHibernate(Fluent)を使ってStartとEndの日付列を持つフラットなテーブル構造を保つ必要がありますか?そうは思いませんが、事前に知っておくと良いです。 –

+0

DateRangeを値オブジェクトとして実装し、NHibernateで 'コンポーネント'として使用することができます。 次に、開始日と終了日の列を持つフラットテーブル構造を維持することができます。 –

5

.NET 4.0以降では、複数の値を扱うタプル<型が追加されました。

タプルタイプでは、独自の値の組み合わせをオンザフライで定義することができます。あなたの問題は非常に一般的で、関数が複数の値を返そうとしているときと似ています。以前は、変数を使用するか、関数の応答のためだけに新しいクラスを作成する必要がありました。

Tuple<DateTime, DateTime> dateRange = 
    new Tuple<DateTime, DateTime>(DateTime.Today, DateTime.Now); 

どのルートをとっても、正しいアプローチをとっていると思います。あなたは、一緒にペアになった2つの日付が本当に意味を与えています。これは、自己文書化コードであり、コードの構造上、最も優れた方法です。

関連する問題