Pourquoi DateTime.Now une propriété et non une méthode?

Après avoir lu cette entrée de blog: http://wekeroad.com/post/4069048840/when-should-a-method-be-a-property ,

Je me demande pourquoi Microsoft a choisi C #:

DateTime aDt = DateTime.Now; 

au lieu de

 DateTime aDt = DateTime.Now(); 
  • Les meilleures pratiques indiquent: Utilisez une méthode lorsque vous appelez le membre deux fois de suite pour obtenir des résultats différents.
  • Et DateTime.Now est un exemple parfait de méthode / propriété non déterministe.

Savez-vous s’il y a une raison pour ce design?
Ou si c’est juste une petite erreur?

Je crois en CLR via C #, Jeffrey Richter mentionne que DateTime.Now est une erreur.

La classe System.DateTime a une propriété readonly Now qui renvoie la date et l’heure actuelles. Chaque fois que vous interrogez cette propriété, elle renvoie une valeur différente. C’est une erreur, et Microsoft souhaite qu’ils puissent réparer la classe en faisant de Now une méthode plutôt qu’une propriété.

CLR via C # 3rd Edition – Page 243

C’est en fait déterministe; sa sortie n’est pas aléatoire, mais repose sur quelque chose d’assez prévisible.

L’heure actuelle change tout le temps; donc pour être relativement “pareil” à chaque appel, cette valeur doit changer pour que chaque fois qu’elle soit appelée, elle renvoie l’heure actuelle.

MODIFIER:

Cela m’est venu à l’esprit: Bien sûr, deux appels ultérieurs à un object getter peuvent renvoyer des résultats différents, si quelque chose modifiait la valeur de la propriété dans l’intervalle. Les propriétés ne sont pas supposées être des Constants .

Donc, c’est ce qui se passe (conceptuellement) avec DateTime.Now ; sa valeur est changée entre les appels suivants.

Les directives ne sont que cela, pas des règles ssortingctes.

Ces directives sont destinées aux objects avec état et, en réalité, tentent de dire que les propriétés ne doivent pas muter un object. DateTime.Now est une propriété statique, l’appel ne modifie donc pas un object. C’est aussi simplement refléter l’état naturel du temps, ne rien changer. Il s’agit simplement d’observer une timer en constante évolution.

Donc, le point est, ne créez pas de propriétés qui changent l’état de l’object. Créez des propriétés qui observent simplement l’état de l’object (même si l’état change en externe).

Comme autre exemple, regardons la longueur d’une chaîne. Ceci est une propriété, mais la longueur de la chaîne peut changer d’invocation en appel si quelque chose d’autre change la chaîne en externe. C’est fondamentalement ce qui se passe, le temporisateur est modifié de manière externe, Now reflète simplement son état actuel, tout comme ssortingng.Length ou toute autre propriété de ce type.

Selon MSDN, vous devez utiliser une propriété lorsque quelque chose est un membre de données logique de l’object:

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

Continuez à énumérer les cas où une méthode serait plus appropriée. Ce qui est ironique, c’est que l’une des règles pour une méthode est de l’utiliser lorsque des appels successifs peuvent renvoyer des résultats différents et bien sûr que Now répond à ces critères.

Personnellement, je pense que cela a été fait pour éliminer les besoins en extra (), mais j’ai trouvé l’absence de () déroutant; il m’a fallu un peu de temps pour passer de l’ancienne approche en VB / VBA.

En décidant de “méthode versus propriété”, un test suggéré est “les appels successifs renverront-ils des résultats différents”. Je dirais qu’un meilleur test est la question similaire, mais pas identique, “l’appel de la routine affectera-t-il le résultat des appels futurs à des routines identiques ou différentes?” Dans la plupart des cas, les réponses aux deux questions seront les mêmes, car la raison la plus fréquente pour laquelle les appels ultérieurs à une routine donneront des résultats différents de ceux du premier serait que le précédent a renvoyé un appel différent. résultat qu’il aurait autrement.

Dans le cas de DateTime.Now, la seule manière dont un appel affecterait la valeur renvoyée par un autre serait que le temps d’exécution pris par le premier appel provoque le deuxième appel de manière mesurable plus tard qu’il ne le serait autrement. Bien qu’un pédant puisse considérer le passage du temps comme un effet secondaire modifiant le statut du premier appel, je suggérerais qu’il y a beaucoup de propriétés qui prennent plus de temps à exécuter que DateTime.Maintenant, et donc un appel à l’un de ceux-ci aurait une plus grande probabilité de modifier la valeur renvoyée par un appel DateTime.Now ultérieur.

Notez que si la routine “get time” était un membre de classe virtuel plutôt qu’un membre statique, cela déplacerait l’équilibre en faveur d’une méthode; Alors que l’implémentation “attendue” n’affecterait pas l’état d’un object, il serait vraisemblable – ou du moins plausible – que certaines implémentations aient des effets secondaires. Par exemple, l’appel de Now sur un object RemoteTimeServer peut tenter d’obtenir l’heure d’un serveur distant, ce qui peut avoir des effets secondaires considérables sur le rest du système (par exemple, en faisant en sorte qu’une ou plusieurs machines mettent en cache les informations de routage DNS / IP). , de sorte que la prochaine tentative d’access au même serveur s’effectue plus rapidement (100 ms).

Comme il n’y a pas de règles de contour sur le moment d’utiliser une méthode et une propriété, DateTime.Now est vraiment une simple lecture de la propriété exposée de l’état du serveur, il peut changer constamment, mais DateTime.Now n’affecte jamais l’état d’aucune propriété , object ou pas, donc c’est une propriété dans le Framework.