.net 我应该创建一个DateRange对象吗?

.net 我应该创建一个DateRange对象吗?,.net,model,tuples,date-range,.net,Model,Tuples,Date Range,一些my domain对象包含一对开始日期和结束日期属性的日期范围: 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; s

一些my domain对象包含一对开始日期和结束日期属性的日期范围:

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类的一个好处是集中验证开始日期之后的结束日期,它将简化我的方法签名:

abstract public int Foo(DateRange dateRange);
abstract public decimal Bar(DateRange dateRange);
abstract public ICollection<DateRange> FooBar(DateRange dateRange);
抽象公共intfoo(DateRange-DateRange);
抽象公共十进制条(DateRange DateRange);
抽象公共ICollection FooBar(DateRange DateRange);
我只是不确定DateRange类不会给我带来更多的麻烦。意见


附带问题:我是否错过了BCL中的通用元组类?我知道在不同的名称空间中有一些非常特殊的名称。用C5类型污染我的公共域方法签名感觉非常、非常肮脏。

如果你对日期做了大量工作,是的-范围可能很方便。这实际上是非常罕见的情况之一,您可能应该将其作为
结构编写(不可变)。然而,请注意,“野田佳彦时间”可能会给你所有这些和更多(当它完成时)。我以前做过调度软件;我有两个这样的结构(用于稍微不同的工作)

注意,没有一个方便的BCL构造来实现这一点


还有——想想当你有一个范围时,你可以集中的所有奇妙的方法(可能还有操作符);“包含”(指一个日期时间?另一个范围?包括/不包括限制?)“相交”,由(一个时间跨度)偏移,等等。有一个类型来处理它的明确的案例。请注意,在ORM级别,如果您的ORM支持复合值,这将更容易实现—我相信NHibernate支持复合值,可能还有EF 4.0。

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


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

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

我有一个您可能感兴趣的
范围
类型,它当然有助于简单的
日期时间
操作。参考Marc的答案,我不记得这是一个结构还是一个类-当然,欢迎您更改它

由于Marc的泛型诡计(至少假设您使用的是.NET3.5,它在2.0中是可行的,但目前还不受支持),它很好而且很容易实现

Range-Range=19.June(1976.To)(DateTime.Today);
foreach(范围.Step中的日期时间日期(1.Days())
{
//这一天我还活着
}
(这也使用了一系列扩展方法——对测试比生产更有用。)


为了解决Marc答案中的另一点,我们当然能够比.NET API更恰当地表达日期的概念,但目前我们没有类似于范围的东西……这是一个好主意-我添加了一个。

正如Mark和Jon已经提到的,我将创建一个值类型,它是不可变的pt将其实现为一个结构,并实现
IEquatable
IComparable
接口


当使用类似NHibernate的ORM时,您将能够在表示实体的表中存储值类型。

在.NET 4.0或更高版本中,添加了元组类型以处理多个值

使用元组类型,您可以动态定义自己的值组合。您的问题非常常见,类似于函数要返回多个值时的问题。以前,您必须使用out变量或仅为函数的响应创建一个新类

Tuple<DateTime, DateTime> dateRange =
    new Tuple<DateTime, DateTime>(DateTime.Today, DateTime.Now);
元组日期范围=
新元组(DateTime.Today,DateTime.Now);

无论您选择哪种方式,我认为您肯定采取了正确的方法。您给了两个日期配对的真正意义。这是自文档化代码,并且以最好的方式,就在代码结构中。

鉴于这是一种重构,可以更好地处理日期和范围操纵,我想这确实会使nse给它上一堂课。我只希望我在这个项目上使用NHibernate。如果我自己这么说的话,那么所有的时间都浪费在写一篇相当不错的文章上了,但是相比之下,DAL显得有些苍白。不过,下一个项目,我现在正在玩它,以掌握它的窍门。因此,拥有DateRange子对象并不难,但要用Start保持平表结构应该不会太难使用NHibernate(Fluent)的和结束日期列?我不这么认为,但最好提前知道。您可以将DateRange实现为值对象,并在NHibernate中将其作为“组件”使用。然后,您确实可以保留带有开始和结束日期列的平面表结构。我将我接受的答案改为您的答案。在阅读范围代码后,我决定使用DateTime p作为DateRange域类核心的参数化版本。它为我提供了80%的帮助。感谢您的贡献。@JonSkeet很高兴您在nuget上有扩展!@Shimmy:嗯,现在它们应该是扩展了……但是MiscUtil在nuget上,作为预发布:而不是range.Step(1.days())尝试range.Step(x=>x.AddDays(1))@Demodave:我可以更改库以接受它,但我认为现在不会这样做。我肯定认为DateRange类会有所帮助。我前一段时间开始编写基础工作:@AdamNaylor:您的链接似乎已关闭。。。
Range<DateTime> range = 19.June(1976).To(DateTime.Today);

foreach (DateTime date in range.Step(1.Days())
{
    // I was alive in this day
}
Tuple<DateTime, DateTime> dateRange =
    new Tuple<DateTime, DateTime>(DateTime.Today, DateTime.Now);