为什么是DateTime.Now属性而不是方法?
看完这个博客条目后: http : //wekeroad.com/post/4069048840/when-should-a-method-be-a-property ,
我想知道为什么微软在C#中select:
DateTime aDt = DateTime.Now;
代替
DateTime aDt = DateTime.Now();
- 最佳实践说:连续两次调用成员时使用方法产生不同的结果
-
DateTime.Now
是非确定性方法/属性的完美例子。
你知道这个devise是否有任何理由?
或者如果这只是一个小错误?
我相信通过C#CLR,Jeffrey Richter提到DateTime.Now是一个错误。
System.DateTime类具有一个只读的Now属性,它返回当前的date和时间。 每次查询该属性时,都会返回一个不同的值。 这是一个错误,微软希望他们能够通过使Now成为一个方法而不是一个属性来修复这个类。
CLR通过C#第3版 – 页面243
它实际上是确定性的; 它的输出不是随机的,而是基于相当可预测的东西。
“当前时间”一直在变化; 所以与每次调用相对“相同”,该值必须改变,以便每次调用时都返回当前时间。
编辑:
这只是发生在我身上:当然,如果在过渡期内某些属性值发生了变化,那么随后的两次对属性getter的调用可能会返回不同的结果。 属性不应该是Constants
。
所以,这就是(在概念上) DateTime.Now
发生的事情; 它的价值正在随后的调用之间改变。
准则就是这样,不是硬性规定。
这些准则是针对有状态对象的,实际上是试图说属性不应该改变对象。 DateTime.Now是一个静态属性,所以调用它不会改变对象。 这也仅仅反映了时间的自然状态,没有任何改变。 这只是观察一个不断变化的计时器。
所以重点是,不要创build改变对象状态的属性。 创build仅仅观察对象状态的属性(即使外部状态发生变化)。
再举一个例子,我们来看看一个string的长度。 这是一个属性,但是如果其他内容从外部改变string的话,string的长度可以从调用改变为调用。 这基本上是怎么回事,计时器正在外部改变,现在只是反映其当前状态就像string.Length或任何其他这样的属性。
根据MSDN,当某事物是对象的逻辑数据成员时,你应该使用一个属性:
http://msdn.microsoft.com/en-us/library/bzwdh01d%28VS.71%29.aspx#cpconpropertyusageguidelinesanchor1
继续列出方法更合适的情况。 具有讽刺意味的是,一个方法的一个规则就是使用它,当连续的调用可能返回不同的结果,当然现在肯定会符合这个标准。
我个人认为这是为了消除extra()的需求,但是我发现没有()混淆; 我花了一些时间从VB / VBA的旧方法转移。
在决定“方法与财产”时,一个build议的testing是“将连续调用返回不同的结果”。 我认为一个更好的testing是类似的,但不是相同的问题,“调用例程会影响未来调用相同或不同的例程的结果吗? 在大多数情况下,这两个问题的答案都是一样的,因为到目前为止,最常见的原因是后来调用例程会产生与前者不同的结果,前者会导致后来的调用返回不同的结果结果比其他方式会有的结果。
在DateTime.Now的情况下,一个调用会影响另一个返回的值的唯一方法是,如果第一次调用所花费的执行时间导致第二次调用发生的时间晚于其他调用发生的时间。 尽pipe一个迂腐者可能会认为时间的stream逝是第一次调用的改变状态的副作用,但是我build议有很多属性比DateTime.Now执行花费更长的时间,因此对任何这些属性的调用都会有更改由后续DateTime.Now调用返回的值的可能性更大。
请注意,如果“get time”例程是一个虚拟类成员,而不是一个静态成员,那么这将改变平衡,使之成为一种方法。 虽然“预期的”实现不会影响任何对象的状态,但是可能(或者至less是合理的)某些实现可能有副作用。 例如,在RemoteTimeServer对象上调用Now可能会尝试从远程服务器获取时间,而这种尝试可能会对系统的其他部分产生相当大的副作用(例如,通过使一台或多台计算机cachingDNS / IP路由信息,这样访问同一台服务器的下一次尝试将以100ms的速度完成)。
由于关于何时使用方法和属性没有明确的规定,DateTime.Now确实只是读取服务器状态的暴露属性,它可能会不断变化,但是DateTime.Now不会影响任何属性的状态,对象还是什么都不是,所以它是框架中的一个属性。