60 votes

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

Après avoir lu cet article de blog : http://wekeroad.com/post/4069048840/when-should-a-method-be-a-property ,

Je me demande pourquoi Microsoft a choisi le C# :

DateTime aDt = DateTime.Now;

au lieu de

DateTime aDt = DateTime.Now();
  • Les bonnes pratiques disent : Utilisez une méthode lorsque le fait d'appeler le membre deux fois de suite produit des résultats différents.
  • Et DateTime.Now est un parfait exemple de méthode/propriété non déterministe.

Savez-vous s'il y a une raison pour cette conception ?
Ou si c'est juste une petite erreur ?

8 votes

La (date)heure n'est qu'une illusion : tout se passe maintenant. C'est donc une propriété :)

3 votes

Hehe... relativement parlant, la valeur ne change jamais ; elle est toujours Now . Si la structure contenait des nombres différents dans ses champs, alors la valeur changerait par rapport à Now ! Ach... cerveau... douleur...

1 votes

@Andrew : Donc devrait-il retourner un Func<DateTime> ? :)

49voto

devdigital Points 22495

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

La classe System.DateTime possède une propriété readonly Now qui renvoie la date et l'heure actuelles. Chaque fois que vous interrogez cette propriété cette propriété, elle renvoie une valeur différente. C'est une erreur, et Microsoft souhaite que corriger cette classe en faisant de Now une méthode au lieu d'une propriété.

CLR via C# 3ème édition - Page 243

2 votes

J'ai toujours considéré cela comme une erreur et j'écris toujours Now() d'abord, sigh's au moins une fois, puis j'utilise backspace deux fois.

12 votes

Je respecte Jeffrey et tout ça, mais il n'a pas cité de source pour cela, ce qui me fait penser qu'il a fait sa propre interprétation. DateTime.Now est une condition exceptionnelle, mais elle est conforme aux directives dans tous les autres cas. Je ne pense pas qu'ils auraient changé cela même s'ils le pouvaient. Sinon, ils l'auraient déprécié et introduit une méthode.

3 votes

Je suis d'accord, c'est l'interprétation de Jeffrey mais je le crois car on ne peut pas avoir une propriété et une méthode avec le même nom dans une classe (donc créer la méthode et garder la propriété dépréciée n'est pas possible).

7voto

Andrew Barber Points 25990

Il est en fait déterministe ; sa sortie n'est pas aléatoire, mais repose sur quelque chose de tout à fait prévisible.

L'"heure actuelle" change tout le temps ; donc, pour être relativement "la même" à chaque appel, cette valeur doit changer de façon à ce que, chaque fois qu'elle est appelée, elle renvoie l'heure actuelle.

EDIT :

Je viens de penser à ça : Bien sûr, deux appels ultérieurs à un récupérateur de propriété puede retourner des résultats différents, si quelque chose a changé la valeur de la propriété entre-temps. Les propriétés ne sont pas censées être Constants .

Donc, c'est ce qui se passe (conceptuellement) avec DateTime.Now ; sa valeur est modifiée entre les appels ultérieurs qui lui sont adressés.

1 votes

Dans la réalité, c'est prévisible, mais sur un ordinateur, ça ne l'est pas. Un Now() est une fonction avec beaucoup de marges d'erreur. Je ne suis pas sûr de la façon dont Now est spécifié mais avec une horloge normale, elle pourrait, en fonction de l'implémentation et du matériel, retourner un nombre tel que a=DatetTime.Now ; b=DateTime.Now ; (b-a) < 0

0 votes

Le résultat que nous obtenons ne l'est peut-être pas, mais conceptuellement parlant, "maintenant" est absolument déterministe. Je n'ai pas vraiment d'avis tranché sur la question, je me suis juste dit que c'était une bonne question idiote du vendredi après-midi :P

0 votes

Je pense que c'est une très bonne et sérieuse question en fait. L'abus des propriétés doit cesser ! En fait, je ne suis pas du tout pour les propriétés. Elles sont un désordre sans intellisense et vous finissez par initialiser des valeurs dont vous n'avez pas besoin juste parce qu'il "pourrait être une propriété que vous changez ensuite, et alors il peut causer une division par zéro" et similaire.

4voto

Oded Points 271275

Je ne sais pas si c'est la réponse, mais on pourrait argumenter que si la propriété renvoie toujours la propriété actuel il ne produit pas un résultat différent (il renvoie l'heure actuelle).

Cependant, il est définitivement un membre logique de DateTime et en tant que tel, il convient parfaitement à une propriété.

4voto

Cat Man Do Points 11771

Selon MSDN, vous devez utiliser une propriété lorsque quelque chose est un membre logique de l'objet :

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

Ils poursuivent en énumérant 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, Now répond certainement à ce critère.

Personnellement, je pense que cela a été fait pour éliminer le besoin d'un () supplémentaire, mais j'ai trouvé l'absence de () déroutante ;

3voto

Erik Funkenbusch Points 53436

Les lignes directrices sont pas des règles strictes et rapides.

Ces lignes directrices sont destinées aux dynamiques des objets, et, en réalité, sont en train de dire que les propriétés ne doivent pas muter un objet. DateTime.Maintenant, est une propriété statique, de sorte que l'appelant n'a pas muter un objet. C'est aussi que refléter l'état naturel de l'heure, de ne pas changer quoi que ce soit. C'est la simple observation d'une évolution constante de la minuterie.

Donc, le fait de ne pas créer des propriétés qui changent l'état de l'objet. Faire créer des propriétés que le simple fait d'observer l'état de l'objet (même si les changements d'état de l'extérieur).

Comme autre exemple, regardons la longueur d'une chaîne. C'est une propriété, mais la longueur de la chaîne peut changer d'une invocation à l'invocation si quelque chose d'autre de modifier la chaîne de l'extérieur. C'est fondamentalement ce qui se passe, le compte à rebours est en cours de modification à l'extérieur, Maintenant, juste reflète son état actuel seulement comme une chaîne de caractères.Longueur ou de tout autre bien.

1 votes

Les chaînes de caractères sont immuables, leur longueur ne peut donc pas changer. Un meilleur exemple est List<T> dont Count peut changer d'une invocation à l'autre si un élément a été ajouté ou supprimé entre-temps.

0 votes

Les chaînes de caractères sont immuables, mais cela ne signifie pas que leur référence l'est. C'est pourquoi j'ai dit "si quelque chose d'autre change la chaîne de manière externe", je n'ai pas dit "change la longueur". Mais vous avez raison.

0 votes

Remplacez StringBuilder par String, et la longueur d'une instance particulière sera effectivement mutable. D'ailleurs, je pense que StringBuilder.Length devrait être une propriété en lecture seule, et qu'il devrait y avoir des méthodes Truncate, Pad, et SetLength ; les deux dernières ayant un paramètre optionnel pour le caractère de remplissage.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X