为什么DateTime.Now属性而不是方法?

时间:2011-03-25 20:47:45

标签: c# .net datetime

阅读此博客文章后:http://wekeroad.com/post/4069048840/when-should-a-method-be-a-property

我想知道微软为何选择C#:

DateTime aDt = DateTime.Now;

而不是

DateTime aDt = DateTime.Now();
  • 最佳实践说:在连续两次调用成员时使用方法会产生不同的结果
  • DateTime.Now是非决定性方法/财产的完美范例。

您知道该设计是否有任何理由?
或者,如果这只是一个小错误?

6 个答案:

答案 0 :(得分:47)

我相信通过C#进行CLR,Jeffrey Richter提到DateTime.Now是一个错误。

  

System.DateTime类具有只读   现在返回当前日期和时间的属性。每次你查询这个   属性,它将返回不同的值。这是一个错误,微软希望如此   他们可以通过将Now设为方法而不是属性来修复类。

CLR通过C#第3版 - 第243页

答案 1 :(得分:7)

它实际上是确定性的;它的输出不是随机的,而是基于可预测的东西。

“当前时间”一直在变化;因此,为了与每次调用相对“相同”,该值必须改变,以便每次调用它时,它都会返回当前时间。

修改

这只是发生在我身上:当然,如果某些内容在过渡期间更改了属性值,则对属性getter 的两次后续调用可以返回不同的结果。属性不应该是Constants

所以,这就是DateTime.Now所发生的事情(概念上);它的值在后续调用之间发生变化。

答案 2 :(得分:3)

指南就是这样,而不是硬性规则。

这些指南适用于有状态对象,实际上试图说属性不应该改变对象。 DateTime.Now是一个静态属性,因此调用它不会改变对象。它也只是反映了自然的时间状态,而不是改变任何东西。它只是观察不断变化的计时器。

所以关键是,不要创建改变对象状态的属性。创建仅观察对象状态的属性(即使状态在外部发生变化)。

作为另一个例子,让我们看一下字符串的长度。这是一个属性,但是如果其他东西在外部更改字符串,则字符串的长度可以从调用更改为调用。这基本上是正在发生的事情,计时器正在外部更改,现在只是将其当前状态反映为string.Length或任何其他此类属性。

答案 3 :(得分:2)

根据MSDN,当某个东西是对象的逻辑数据成员时,你应该使用一个属性:

http://msdn.microsoft.com/en-us/library/bzwdh01d%28VS.71%29.aspx#cpconpropertyusageguidelinesanchor1

继续列出方法更合适的情况。具有讽刺意味的是,方法的一个规则就是在连续调用可能返回不同结果时使用它,当然现在肯定符合该标准。

我个人认为这样做是为了消除extra()的需要,但我发现没有()令人困惑;我花了一些时间从VB / VBA中的旧方法转移。

答案 4 :(得分:2)

在决定“方法与属性”时,建议的测试是“将连续调用返回不同的结果”。我建议更好的测试是类似但不完全相同的问题,“调用例程会影响未来调用相同或不同例程的结果吗?”在大多数情况下,两个问题的答案都是相同的,因为到目前为止,后来调用例程的最常见原因会产生与前者不同的结果,那就是前者引起的后来的调用返回的结果与原本不同。

在DateTime.Now的情况下,一次调用影响另一次调用返回的值的唯一方法是,如果第一次调用所花费的执行时间导致第二次调用发生的时间明显晚于其他情况。虽然一个学究者可能会认为时间的流逝是第一次调用的状态改变的副作用,但我会建议有许多属性需要比DateTime.Now执行更长的时间,因此调用任何这些属性都会有更有可能更改后续DateTime.Now调用返回的值。

请注意,如果“get time”例程是虚拟类成员而不是静态成员,那么这将改变平衡,使其成为一种方法;虽然“预期的”实现不会影响任何对象的状态,但某些实现可能会产生副作用,或者至少是合理的。例如,在RemoteTimeServer对象上调用Now可能会尝试从远程服务器获取时间,并且此类尝试可能会对系统的其余部分产生相当大的副作用(例如,通过使一台或多台计算机缓存DNS / IP路由信息) ,这样下次尝试访问同一台服务器的速度将快100ms。)

答案 5 :(得分:0)

由于没有关于何时使用方法和属性的明线规则,DateTime.Now实际上只是读取服务器状态的公开属性,它可能会不断变化,但DateTime.Now永远不会影响状态任何属性,对象或什么不是,所以它是框架中的属性。