我应该制作一个DateRange对象吗?
我的一些领域对象包含日期范围为一对的开始和结束日期属性:我应该制作一个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);
最后一个让我奇怪...我应该实现一个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;
一个日期范围类的好处是集中验证和这将简化我的方法签名:
abstract public int Foo(DateRange dateRange);
abstract public decimal Bar(DateRange dateRange);
abstract public ICollection<DateRange> FooBar(DateRange dateRange);
我只是不知道,一类DATERANGE不会得到我到超过其价值的麻烦。意见?
旁边的问题:我错过了BCL某处的通用通用元组类吗?我知道在各种命名空间中有一些非常特殊的东西。使用C5类型污染我的公共领域方法签名感觉非常非常肮脏。
不,你没有错过一个通用类。
我有一个Range
类型MiscUtil您可能会感兴趣 - 它肯定会使简单的DateTime
操作。参考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。
对不起,如果我误解了野田时间 - 这看起来很适合那些对时间感兴趣的人。 – 2009-12-04 08:04:37
不,这很好 - 如果你没有提到它,我不确定我是否想过为该项目添加一个功能请求:)我认为这是一个相当普遍的要求 - 棘手的一点是工作需要什么来适应人们会需要的各种调整! – 2009-12-04 08:10:10
有趣的语法。 – 2009-12-04 08:15:22
如果你做了很多日期的工作,是的 - 一个范围可以很方便。这实际上就是其中一种很罕见的情况,其中您应该将编写为struct
(不可变)的。但是,请注意,“野田时间”可能会给你所有这些和更多(当它完成时)。我之前做过调度软件;我有几个这样的结构(对于稍微不同的工作)。
请注意,这没有一个方便的BCL构造。
此外 - 想想你有一个范围时,你可以集中所有美好的方法(和可能的运营商); “包含”(另一个范围的日期时间?包括/不包括限制?),“相交”,偏移量(时间跨度)等。确定具有处理它的类型的情况。请注意,在ORM级别,如果您的ORM支持复合值,这会更容易一些 - 我相信NHibernate可以,也可能是EF 4.0。
哦,是的,野田。等待它...... – 2009-12-04 08:01:37
鉴于这是一个重构,以更好地处理日期和范围的操作,我想它是有道理的,给它一个类。 我只希望我在这个项目上使用NHibernate。如果我自己这么说,那么所有这些小时都会写得相当不错,但相比之下,DAL却显得苍白无力。下一个项目,但。我现在正在玩它来获取它的窍门。 – 2009-12-04 08:22:41
我不知道任何本地.NET类的DATERANGE性质。最接近的可能是DateTime + TimeSpan或DateTime/DateTime组合。
我想你想要的是相当合理的。
正如马克和乔恩已经提到的那样,我会将它创建为一个值类型,它是不可变的。我会选择将它作为一个结构来实现,并实现IEquatable和IComparable接口。
当使用像NHibernate这样的ORM时,您将能够在表示实体的表格中存储值类型。
因此,让DateRange子对象应该不会很困难,但使用NHibernate(Fluent)保持开始和结束日期列的平坦表结构?我不这么认为,但事先知道是很好的。 – 2009-12-04 08:44:16
你可以实现你的DateRange作为一个值对象,并在NHibernate中用它作为'组件'。 然后,你确实可以保持平坦的表结构与开始和结束日期列。 – 2009-12-04 08:49:30
在.NET 4.0或更高版本中,Tuple <>类型被添加来处理多个值。
使用元组类型,您可以即时定义自己的值组合。你的问题是非常普遍的,并且与函数想要返回多个值时类似。以前,您只能使用变量或为函数的响应创建一个新类。
Tuple<DateTime, DateTime> dateRange =
new Tuple<DateTime, DateTime>(DateTime.Today, DateTime.Now);
无论你走哪条路线,我都认为你确实采取了正确的做法。你给予两个日期配对在一起的真正意义。这是自我记录代码,最好的方式就是在代码结构中。
我绝对认为DateRange类可以提供帮助。我开始为后面一段时间写下基础:http://www.adamjamesnaylor.com/2012/11/04/C-DateRange-Class.aspx – 2012-11-07 15:38:39
@AdamNaylor:您的链接似乎已经停止...... – testing 2016-01-11 15:57:20