我应该做一个DateRange对象?

我的几个域对象包含date范围作为一对开始和结束date属性:

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

最后一个让我想知道…我应该实现DateRange类吗? 我不知道在BCL有一个。

根据我的经验,使对象层次更深往往使事情复杂化。 这些对象确实发送到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类的好处是集中validation开始date之后的结束date,这将简化我的方法签名:

 abstract public int Foo(DateRange dateRange); abstract public decimal Bar(DateRange dateRange); abstract public ICollection<DateRange> FooBar(DateRange dateRange); 

我只是不确定DateRange类不会让我陷入比它的价值更麻烦的地步。 意见?

旁边的问题:我在BCL的地方错过了一个通用的通用元组类吗? 我知道在各种命名空间中有一些非常特殊的东西。 污染我的公共领域方法签名与C5types感觉非常,非常肮脏。

不,你没有错过一个通用课程。

我在MiscUtil中有一个Rangetypes,你可能会感兴趣的 – 这当然使得简单的DateTime操作。 参考Marc的回答,我不记得这是一个结构还是一个类,当然欢迎您改变它。

由于Marc的generics神秘(假设你至less使用了.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 } 

(这也使用了一堆扩展方法 – 对于testing比生产更有用)。

为了解决Marc的回答中的另一个问题, Noda Time肯定能够比.NET API更适合地expressiondate的概念,但目前我们没有任何类似的范围…这是个好主意虽然 – 我已经添加了一个function请求 。

如果你用date做很多工作,是的 – 一个范围可以很方便。 这实际上是其中一种罕见的情况,你应该把它写成一个struct (不可变的)。 但是,请注意,“野田时间”可能会给你所有这些和更多(当它是完整的)。 我之前做过调度软件; 我有一些这样的结构(略有不同的工作)。

请注意,这没有一个方便的BCL构造。

另外 – 想想你有一个范围,你可以集中所有美好的方法(可能是运营商); “包含”(包括/不包括限制的另一个范围的date时间?),“相交”,偏移量(时间跨度)等等。具有处理types的确定的情况。 请注意,在ORM级别,如果您的ORM支持复合值,这会更容易一些 – 我相信NHibernate可以,也可能是EF 4.0。

在.NET 4.0或更高版本中,添加了Tuple <>types来处理多个值。

使用元组types,您可以即时定义自己的值组合。 你的问题很常见,和函数想要返回多个值时类似。 以前,您只能使用variables或为函数的响应创build一个新类。

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

无论你走哪条路线,我都认为你确实采取了正确的做法。 你给予两个date配对在一起的真正意义。 这是自我logging的代码,最好的方式就是在代码结构中。

我不知道DateRange本质的任何本地.NET类。 最接近的可能是DateTime + TimeSpan或DateTime / DateTime组合。

我想你想要的是相当合理的。

正如马克和乔恩已经提到的那样,我将把它创造成一种价值型,这是不变的。 我会select实现它作为一个结构,并实现IEquatable和IComparable接口。

当使用像NHibernate这样的ORM时,您将能够将值types存储在表示实体的表中。