web-dev-qa-db-fra.com

Y a-t-il quelque chose de mal à écrire des méthodes getter / setter en C #?

Je suis un Java dev pour presque toute ma programmation (au moins sur le lieu de travail) mais je fais un peu Unity pour le plaisir. J'ai utilisé plusieurs fois les propriétés C # et elles sont pratiques pour fournissent toujours l'encapsulation sans avoir à écrire les méthodes getter et setter.

Cela dit, y a-t-il un inconvénient à écrire des méthodes getter et setter réelles pour les champs (à part mon temps)? Supposons que cela fait partie de mon code Unity personnel pour le plaisir et non dans un environnement de travail ou de développement partagé.

4
JaredSK74

Les propriétés C # sont constituées de méthodes. Ainsi, en utilisant des méthodes au lieu de propriétés, vous n'obtenez aucun avantage d'exécution.

Au lieu de cela, il s'agira de la productivité des développeurs et de la lisibilité de votre code.

La lisibilité est aussi pour vous. Dans quelques mois, lorsque vous avez oublié les détails de votre code et que vous devez le modifier pour corriger un bug ou ajouter une nouvelle fonctionnalité. Même si vous ne vous souciez pas de cela, vous vous souciez probablement d'en faire plus avec la même quantité de code.


Du côté de la productivité, nous avons que les propriétés ont l'avantage d'exiger d'écrire moins de code. Beaucoup plus si nous parlons de propriétés automatiques. Concernant la lisibilité, elles entraînent un code moins détaillé (moins Get, moins Set et moins ()).

Les propriétés peuvent également affecter la découvrabilité. Comme avoir getter et setters entraînera la séparation des méthodes associées au même champ dans intellisense.

Cependant, il existe certains arguments pour les méthodes. Par exemple, si la définition d'une valeur peut échouer, vous pouvez utiliser une méthode et renvoyer bool afin de pouvoir communiquer avec l'appelant en cas d'échec de l'ensemble. Vous pourriez, en théorie, vous en tirer avec une propriété ... après tout, l'appelant peut lire la propriété après l'avoir définie pour vérifier si la valeur a été définie. Cependant, renvoyer bool est une API prête pour les threads.

Un autre cas est celui où la propriété doit effectuer un long calcul pour renvoyer une valeur. L'utilisation d'une méthode signifie qu'elle fait quelque chose en coulisse. De même, l'utilisation d'une méthode au lieu d'une propriété peut signifier que la lecture de la valeur peut avoir des effets secondaires (elle n'est pas pure). Addendum: Ce n'est pas une règle stricte. Pourtant, en général, une méthode fait quelque chose, c'est une action. En revanche, nous nous attendons à pouvoir lire les propriétés à tout moment sans conséquences majeures.

Enfin, si vous avez une propriété qui renvoie un tableau, elle peut être manquée pour un indexeur. Il est préférable de fournir un indexeur réel ou d'utiliser une méthode pour éviter toute confusion.


Soit dit en passant, Alan Kay, qui a inventé le terme orienté objet, n'aime pas les setters. Au lieu de cela, l'état doit être encapsulé. Il a dit:

Beaucoup de soi-disant langages orientés objet ont des setters et quand vous avez un setter sur un objet vous le retransformez en une structure de données.

Pour Alan Kay, laisser des tiers changer l'état de l'objet de manière inattendue est une mauvaise idée.


Dans cet esprit, laissez rencontré vous parler de quelques cas où les propriétés sont une mauvaise conception:

  1. Évitez de fournir des propriétés comme moyen de décider quoi faire. Le code de l'appelant ne devrait pas avoir à lire les propriétés de votre objet pour décider quelle méthode appeler. Encapsulez plutôt cette logique dans les méthodes de votre classe. Autrement dit, avec une conception orientée objet, préférez Dites, ne demandez pas .

  2. Évitez les propriétés qui modifient le comportement des méthodes. Si vous les avez, vous vous retrouverez avec du code qui sauvegarde la valeur d'une propriété, modifiez la valeur, appelle la méthode, puis restaurez la valeur. Ajoutez plutôt cette valeur en tant que paramètre à la méthode (même si vous devez l'ajouter à pratiquement toutes les méthodes de la classe). Cela rend l'API beaucoup plus facile à utiliser, suit le principe du moindre étonnement, et c'est mieux pour le code thread-safe.


Les propriétés, en particulier les propriétés en lecture seule, restent très utiles pour la journalisation et le débogage. Il y a aussi des choses qui dépendent des propriétés pour fonctionner, comme certaines formes de sérialisation et de liaison de données.

7
Theraot

Gardez à l'esprit que les propriétés sont "méthodes getter et setter réelles". Une propriété n'est ni plus ni moins qu'une ou deux méthodes, ainsi qu'un morceau de métadonnées disant "c'est une propriété". La syntaxe pour appeler une méthode de propriété est différente de la syntaxe pour appeler une méthode ordinaire, mais à part cela, une méthode de propriété fonctionne exactement de la même manière que toute autre méthode.

Cela dit...

Cela dit, y a-t-il un inconvénient à écrire des méthodes getter et setter réelles pour les champs (à part mon temps)? Supposons que cela fait partie de mon code Unity personnel pour le plaisir et non dans aucune sorte de travail ou d'environnement de développement partagé.

Dans votre propre code personnel? Non, pas vraiment.

Le principal inconvénient est que lorsque d'autres personnes lisent votre code, elles ont probablement une mauvaise idée de ce qui se passe. Si vous écrivez deflection = surface.Deflection, Je vais deviner que trouver la valeur de déviation est rapide et facile. Si vous écrivez deflection = surface.GetDeflection(), je vais deviner que trouver la valeur de déflexion implique quelque chose de lent ou de difficile, comme lire un fichier ou communiquer avec un capteur qui déterminera la déviation.

En d'autres termes, la façon habituelle d'écrire des getters et setters est de les écrire en tant que propriétés C #, donc si vous ne les écrivez pas en tant que propriétés C #, les gens vont supposer que vous aviez une raison particulière de ne pas le faire.

Et, bien sûr, si jamais vous écrivez C # au sein d'une équipe plus tard dans votre vie, l'équipe voudra probablement que vous écriviez des getters et des setters de la manière "normale", donc vous voudrez peut-être prendre l'habitude maintenant .

Mais si vous préférez lire et écrire controller.SetProcVar(aircraft.GetAttitude().GetBankAngle()) que controller.ProcVar = aircraft.Attitude.BankAngle, Cela ne vous causera aucun problème inattendu.

1
Tanner Swett