.net 我应该制作一个 DateRange 对象吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1845493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 13:37:04  来源:igfitidea点击:

Should I make a DateRange object?

.netmodeltuplesdate-range

提问by quentin-starin

A few of my domain objects contain date ranges as a pair of start and end date properties:

我的一些域对象包含日期范围作为一对开始和结束日期属性:

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

And I find myself with a lot of this:

我发现自己有很多这样的:

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

The last one made me wonder ... Should I implement a DateRange class? I'm not aware of one in the BCL.

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

In my experience, making the object hierarchy deeper often complicates things. These objects do get sent to RDLC reports displayed by the ReportViewer control, but that's secondary. I'll bend the view to the model rather than vice versa. We aren't tied to the property names, though, and would be willing to compromise with something like:

根据我的经验,使对象层次结构更深通常会使事情复杂化。这些对象确实会发送到由 ReportViewer 控件显示的 RDLC 报告,但这是次要的。我会将视图弯曲到模型,而不是相反。不过,我们并不依赖于属性名称,并且愿意妥协于以下内容:

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

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

A benefit of a DateRange class would be centralized validation of the end date coming after the start date, and it will simplify my method signatures:

DateRange 类的一个好处是对开始日期之后的结束日期进行集中验证,它将简化我的方法签名:

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

I'm just not sure that a DateRange class won't get me into more trouble than its worth. Opinions?

我只是不确定 DateRange 类不会给我带来比其价值更多的麻烦。意见?

Side question: Did I miss a generic general-purpose tuple class in the BCL somewhere? I know there's some very specific ones floating around in various namespaces. Polluting my public domain method signatures with C5 types feels very, very dirty.

附带问题:我是否错过了 BCL 中某个通用的通用元组类?我知道在不同的命名空间中有一些非常具体的内容。用 C5 类型污染我的公共领域方法签名感觉非常非常脏。

采纳答案by Jon Skeet

No, you didn't miss a general purpose class.

不,您没有错过通用课程。

I have a Rangetype in MiscUtilwhich you may be interested in - and it certainly makes for simple DateTimemanipulation. Referring to Marc's answer, I can't remember whether this is a struct or a class - you'd be welcome to change it of course.

RangeMiscUtil 中有一个您可能感兴趣的类型- 它确实可以进行简单的DateTime操作。参考 Marc 的回答,我不记得这是一个结构体还是一个类——当然欢迎你改变它。

It's nice and easy to step through, due to Marc's generics shenanigans (assuming you're using .NET 3.5, at least - it's feasible with 2.0 but not supported at the moment);

由于 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
}

(That's also using a bunch of extension methods - more useful for test than production.)

(这也使用了一堆扩展方法 - 对测试比生产更有用。)

To address the other point in Marc's answer, Noda Timewill certainly be able to express the concept of a date more appropriately than the .NET API, but we don't have anything like a range at the moment... It's a nice idea though - I've added a feature request.

为了解决 Marc 回答中的另一点,Noda Time肯定能够比 .NET API 更恰当地表达日期的概念,但我们目前没有范围之类的东西......这是一个好主意虽然 - 我添加了一个功能请求

回答by Timothy Gonzalez

In .NET 4.0 or higher the Tuple<> type was added to handle multiple values.

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

With the tuple type you can define your own combination of values on the fly. Your problem is very common and is similar to when a function wants to return multiple values. Previously you had to use out variables or create a new class just for the function's response.

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

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

Whichever route you take, I think you are definitely taking the correct approach. You are giving real meaning to what two dates paired together are. That's self-documenting code and in the greatest way, right in the structure of the code.

无论你走哪条路,我认为你肯定采取了正确的方法。您正在赋予配对在一起的两个日期真正的意义。这是自我记录的代码,并且以最好的方式,就在代码结构中。

回答by Marc Gravell

If you do a lot of work with dates, yes - a range can be handy. This is actually one of those oh-so-rare cases where you shouldprobably write it as a struct(immutable). Note, however, that "Noda Time" will probably give you all of this and more (when it is complete). I've done scheduling software before; I had a couple of such structs (for slightly different jobs).

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

Note, there isn't a handy BCL construct for this.

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

Also - think of all the wonderful methods (and possibly operators) that you can centralise when you have a range; "contains" (of a datetime? of another range? including/excluding limits?), "intersects", offset-by (a timespan), etc. A definitecase for having a type to handle it. Note that at the ORM level, this is easier if your ORM supports composite values - I believe NHibernate does, and possibly EF 4.0.

另外 - 想想当你有一个范围时你可以集中的所有美妙的方法(可能还有操作符);“包含”(日期时间?另一个范围?包括/排除限制?)、“相交”、偏移量(时间跨度)等。具有处理它的类型的明确情况。请注意,在 ORM 级别,如果您的 ORM 支持复合值,这会更容易 - 我相信 NHibernate 支持,并且可能支持 EF 4.0。

回答by o.k.w

I do not know of any native .NET class of the DateRange nature. The closest is probably DateTime+TimeSpan or DateTime/DateTime combination.

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

I think what you want is fairly sound.

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

回答by Frederik Gheysels

As Mark and Jon already mentionned, I would create this as a value-type, which is immutable. I would opt to implement it as a struct, and implement the IEquatable and IComparable interfaces.

正如 Mark 和 Jon 已经提到的,我会将其创建为不可变的值类型。我会选择将它实现为结构体,并实现 IEquatable 和 IComparable 接口。

When using an ORM like NHibernate, you will be able to store the value type inside a table which represents an entity.

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