60

After reading this blog entry : http://wekeroad.com/post/4069048840/when-should-a-method-be-a-property,

I'm wondering why Microsoft choose in C# :

DateTime aDt = DateTime.Now; 

instead of

DateTime aDt = DateTime.Now(); 
  • Best practices say : Use a method when calling the member twice in succession produces different results
  • And DateTime.Now is perfect example of non-determistic method/property.

Do you know if there any reason for that design ?
Or if it's just a small mistake ?

8
  • 8
    (Date)Time is just an illusion: everything is happening Now. So it's a property :) Commented Mar 25, 2011 at 20:54
  • 3
    hehe... relatively speaking, the value never changes; it's always Now. If the struct contained different numbers in its fields, then the value would be changing in relation to Now! Ach.. brain... pain... Commented Mar 25, 2011 at 20:56
  • 1
    @Andrew: So should it return a Func<DateTime> ? :) Commented Mar 25, 2011 at 21:01
  • 6
    I wrote a program that calls DateTime.Now in a loop waiting for it to change. I was able to call it over 16,000 times in succession without it changing. Using UtcNow I got over 1M successive calls before it changed. I think that's sufficient to make it a property. Commented Mar 27, 2011 at 3:37
  • 2
    @Gebe , I suggest to make an agreement: "If calling the method for 42 times in a row returns the same value - it can be converted to a property." Commented May 16, 2013 at 10:25

6 Answers 6

51

I believe in CLR via C#, Jeffrey Richter mentions that DateTime.Now is a mistake.

The System.DateTime class has a readonly Now property that returns the current date and time. Each time you query this property, it will return a different value. This is a mistake, and Microsoft wishes that they could fix the class by making Now a method instead of a property.

CLR via C# 3rd Edition - Page 243

Sign up to request clarification or add additional context in comments.

5 Comments

I've always considered this a mistake and always write Now() first, sigh's atleast once and then use backspace twice.
I respect Jeffrey and all that, but he didn't quote a source for this, which makes me think he was doing his own interpretation. DateTime.Now is an exceptional condition, but fits within the guidelines in all other ways. I don't think they would have changed this even if they could. Otherwise, they'd deprecate it and introduce a method.
I'm agree it's Jeffrey interpretation's but I believe him because you can't have a property and a method with same name in a class (so creating the method and keeping the deprecated property isn't possible)
The same lamentation appears in the .NET Framework Design Guidelines. A more detailed rationale is available in that book. A must read for anyone smart enough to ask this question. ;-)
The excerpt from the book that you're quoting is a part of explanation on author's personal opinion about properties: "Personally, I don’t like properties and I wish that they were not supported in the Microsoft .NET Framework and its programming languages." I can't give enough reasons why this statement is wrong on so many levels.
7

It actually is deterministic; it's output is not random, but is based on something quite predictable.

The 'current time' changes all the time; so to be relatively "the same" with each call, that value must change so that every time it's called, it's returning the current time.

EDIT:

This just occurred to me: Of course, two subsequent calls to a property getter can return different results, if something changed the property value in the interim. Properties are not supposed to be Constants.

So, that's what happening (conceptually) with DateTime.Now; its value is being changed between subsequent calls to it.

6 Comments

In real word its predictable, on a computer it really is not. A Now() is a function with alot of error margins. Iam not sure how Now is specified but with a normal timer/clock it could based on implementation and hardware actually return a number so that a=DatetTime.Now; b=DateTime.Now; (b-a) < 0..
The output we're getting may not be, but conceptually speaking, "now" is absolutely deterministic. I don't really have a strong opinion on this, though; I just thought it was a good, silly Friday afternoon question :P
@stefan - I have yet to and do not expect to lose any sleep over this, either way.
I'm agree on one point, time will continue to run out with or without answer to this question...
Your definition of "deterministic" is erroneous: "Deterministic functions always return the same result any time they are called with a specific set of input values". The word refers to whether or not it is possible to determine the output given nothing more than the function definition and the input. With DateTime.Now this is impossible technet.microsoft.com/en-us/library/aa214775(v=sql.80).aspx
|
4

According to MSDN you should use a property when something is a logical data member of the object:

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

The go on to list out the cases where a method would be more appropriate. What is ironic is that one of the rules for a method is to use it when successive calls may return different results and of course Now certainly meets that criteria.

Personally I think this was done to eliminate the needs for the extra (), but I have found the absence of () confusing; it took me a little while to shift from the old approach in VB/VBA.

Comments

3

Guidelines are just that, not hard and fast rules.

Those guidelines are intended for stateful objects, and in reality are trying to say that properties should not mutate an object. DateTime.Now is a static property, so calling it does not mutate an object. It's also merely reflecting the natural state of time, not changing anything. It is simply observing a constantly changing timer.

So the point is, don't create properties that change the state of the object. Do create properties that merely observe the state of the object (even if the state changes externally).

As another example, let's look at the length of a string. This is a property, but the length of the string can change from invocation to invocation if something else changes the string externally. That's basically what is going on, the timer is being changed externally, Now just reflects its current state just as string.Length or any other such property.

3 Comments

Strings are immutable, so their lengths cannot change. A better exapmle is List<T>, whose Count property can change from one invokation to the next if an element has been added or deleted in the meantime.
Strings are immutable, but that doesn't mean it's reference is. That's why i said "if something else changes the string externally", i did not say "changes the length". But you have a point.
Substitute StringBuilder for String, and the length of a particular instance will indeed be mutable. Incidentally, I would aver that StringBuilder.Length should be a read-only property, and there should be Truncate, Pad, and SetLength methods; the latter two having an optional parameter for the padding character.
2

In deciding "method versus property", a suggested test is "will successive calls return different results". I would suggest that a better test is the similar, but not identical question, "will calling the routine affect the outcome of future calls to the same or different routines?" In most cases, the answers to both the questions will be the same, since by far the most common reason that later calls to a routine will yield different results from the former one would be that the former one caused the later call to return a different result than it otherwise would have.

In the case of DateTime.Now, the only way in which one call would affect the value returned by another would be if the execution time taken by the first call caused the second call to occur measurably later than it otherwise would have. While a pedant might consider the passage of time to be a state-altering side effect of the first call, I would suggest that there are many properties which take longer to execute than DateTime.Now, and thus a call to any of those would have a greater likelihood of changing the value returned by a subsequent DateTime.Now call.

Note that if the "get time" routine were a virtual class member rather than being a static member, that would shift the balance in favor of making it a method; while the "expected" implementation would not affect the state of any object, it would be likely--or at least plausible--that some implementations might have side-effects. For example, calling Now on a RemoteTimeServer object might attempt to get the time from a remote server, and such attempt might have considerable side-effects on the rest of the system (e.g. by causing one or more machines to cache DNS/IP routing information, such that the next attempt to access the same server will complete 100ms faster).

Comments

0

Since there are no brightline rules on when to use a method and a property, DateTime.Now is truly just reading an exposed property of the state of the server, it may be constantly changing, but DateTime.Now never effects the state of any property, object or what not, so it is a property in the Framework.

1 Comment

Unless you considering Heisenberg, in which merely observing something changes its state ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.