in c # Vous pouvez créer un getter / setters de manière plus simple que d'autres langues: ceci crée une variable privée interne que vous ne pouvez pas adresser directement, avec la propriété externe 'Foobar «Pour y accéder directement. P> Ma question est - À quelle fréquence vois-tu cela maltraité? Il semble que cela ait un potentiel élevé de violer souvent les meilleures pratiques d'encapsulation. Ne vous méprenez pas, je l'utilise comme approprié et des variations partielles de celui-ci pour des types de propriétés en écriture en lecture seule, mais quelles sont vos expériences désagréables avec elle d'autres auteurs de votre base de code? P> < p>
4 Réponses :
Il n'y a pas de "abus" dans simplement ne pas écrire le champ manuellement; Et il est bon d'encourager tout accès via la propriété (pas directement sur le terrain) de toute façon! p>
Le plus gros problème que je connaisse est avec sérialisation binaire A >, où il devient un peu délicat de retourner dans un champ régulier sans la faire une version incompatible - mais ... utilisez un sérielizer différent ;-p p>
Ce serait bien s'il y avait une variante réadonnée "appropriée", et si vous n'aviez pas besoin d'utiliser : ceci () code> CTOR-chaîning sur les structures, mais ... MEH! p>
Je suis d'accord. Je pense que les propriétés et peuvent aider à étendre les choses plus tard (surtout si elles sont publiques et que vous vous attendez à ce que quelqu'un d'autre utilise vos cours).
Suivez le pointeur d'instructions rebondissant ici (;)): Propriétés automatiques, vous ne pouvez pas accéder à leurs magasins de support. Si c'est Eadonly, il n'ya aucun moyen de lui donner une valeur du tout i>. Donc, ce serait donc inutile ...
@RCIX: L'idée serait de le déclarer comme un ensemble privé, mais utilisez un [lisonly] code> pour forcer cet accès à être contraint exactement comme
lisonly code> est.
Je n'ai vu aucun abus de cela. Et pour être honnête, je ne vois pas vraiment ce que vous voulez dire, comme je ne vois pas comment cette syntaxe pourrait être maltraitée. P>
Je l'ai vu abusé (à mon avis). En particulier, lorsque le développeur normalement em> écrire: Ils écriront parfois: p> oui , c'est plus court. Oui, de l'extérieur de la classe, il a la même apparence - mais je ne les considère pas comme la même chose, car cette dernière forme permet à la propriété d'être réglée ailleurs dans la même classe. Cela signifie également qu'il n'y a pas d'avertissement si la propriété n'est pas définie dans le constructeur et que le champ n'est pas réadienné pour le CLR. Ce sont des différences subtiles, mais juste pour la deuxième forme car c'est plus simple et ignorer les différences ressemblent à des abus pour moi, même si c'est mineur. P> Heureusement, ceci est maintenant disponible à partir de C # 6: p>
Bon point. Aimerait aussi voir à la fois des propriétés automatiques
J'ai déjà vu cela aussi bien, mais votre prise est intéressante.
Ce n'est pas presque la même chose, car vous avez marqué la variable locale foo comme réadonn. Si elle est réadonnée, elle ne peut être définie nulle part autre que lors de la première initialisation, sinon, on peut accéder d'ailleurs dans la même classe - comme la dernière forme de vous.
Je pense que Beowulf est latéralement en train de faire le point que c'est la partie réadonnée qui rend ce "abusif", qui est assez étroit
@Annakata: Je le vois comme un abus parce que vous prenez un raccourci pour représenter quelque chose qui est comme i> Ce que vous voulez vraiment dire, mais n'est pas en fait i> ce que vous voulez vraiment dire? .
J'espérais également un moyen de marquer le terrain sous-jacent, peut-être via un attribut, mais il semble que cette fonctionnalité ne se présente pas à la libération C # 4. Suce.
@Steven: Je ne pense pas que cela ne faisait jamais partie d'un ensemble de fonctionnalités candidates. Au moins, pas un que j'étais au courant :)
Je suis sûr que tu as raison, Jon, mais ça aurait vraiment dû être, parce que je suis coupable de faire de façon routinière exactement cette erreur et de souhaiter qu'il y ait une alternative qui n'avait pas besoin d'un champ de support explicite. Ma conscience me trouble.
@Steven: Oh je suis totalement d'accord. C'est mon n ° 1 "C'est vraiment simple, s'il vous plaît, faites-le donc" souhaiter pour c # 5. L'équipe sait et j'espère - modulo la normale "même une petite fonctionnalité prend beaucoup de conception, de mise en œuvre et d'effort de test" .
D'autre part, il est souvent utilisé pour faire par exemple. Les entités jouent bien avec des mappeurs O / R, de l'automapper, etc. et se comportent toujours comme s'il n'y a pas de setters d'une perspective extérieure ..
@Rogeraling: quand il est utilisé délibérément i> pour une raison spécifique, c'est bien. Je souhaite juste que ce soit beaucoup plus facile de gérer le cas de "Je veux vraiment qu'il soit totalement réadonnant."
En tant que mise à jour sur le souhait de @ Jonskeet: les propriétés appliquées automatiquement en lecture seule sont désormais disponibles à partir de C # 6.0. Exclure simplement l'ensemble ; code> partie de la syntaxe standard. Vous pouvez également les initialiser sur la même ligne, en ajoutant
= quelquevaleueExpression code>.
Exemple de la syntaxe C # 6.0 que @Dreikin fait référence à, adapté de [link] Stackoverflow.com/a/34743656/1991614 chien de classe publique {nom de chaîne publique {obtenir; } DateTetime publique chippyborn {obtenir; } = Datetime.now; chien public (nom de cordes) {nom = nom; }} code>
@Jonskeet dans la version C # 6, que si je souhaite valider la valeur avant de l'attribuer? Devrais-je le faire dans le constructeur? Mon gut me dit de ne pas sortir depuis que le constructeur peut devenir énorme, mais je ne suis pas sûr.
@SIPO: S'il est passé dans le constructeur, validez-le dans le constructeur. C'est le cas pour toutes les versions de C #, IMO.
@Jonskeet - merci. Si je DO I> doit utiliser un setter privé, il sera préférable de valider la valeur à l'intérieur plutôt que dans le constructeur?
@SIPO: Pourquoi croyez-vous que vous avez besoin d'un setter privé? Si tel est ainsi, vous pouvez la définir des endroits autres que le constructeur, alors vous voulez probablement une validation dans tous ces endroits, il est donc logique de le mettre dans le setter. Si vous utilisez uniquement un setter privé pour que vous puissiez tricher pour faire ressembler «un peu lisez-le», je le ferais correctement et que je dispose d'un champ réadien défini par le constructeur. (Et travaillez sur la mise à niveau vers C # 6 ou ultérieure ...)
@Jonskeet - Il me semble que ce n'est pas la responsabilité du constructeur, mais apparemment, il n'y a pas d'autre option. J'ai suggéré à l'équipe C # pour ajouter une telle caractéristique: VISUALStudio.UserVoice.com/forums/121579-Visual-Studio-ide/...
@SIPO: C'est un paramètre du constructeur, il est donc raisonnable que le constructeur le validait. Mais à ce stade, nous sommes un moyen équitable de la question de la question et la pile de pile n'est pas destinée à la discussion.
Je ne pense pas que les propriétés automatiques sont pires que les propriétés régulières en ce qui concerne l'encapsulation. P>
Si vous voulez dire que certains développeurs utilisent des propriétés automatiques publiques à la place des champs privés, cela est bien sûr erroné et brise l'encapsulation .. P>
Abusé comment exactement? La seule chose abusive à laquelle je peux penser consiste à mettre une méthode de travail de la méthode dans une propriété, et c'est assez mineur
Pourriez-vous donner un exemple où vous pensez que l'utilisation de propriétés automatiques n'est pas appropriée?
@Annakata - que vous ne peut pas b> Faire avec une propriété mise en œuvre automatiquement.
Réflarification - Si vous créez une propriété publique B> lorsque vous voulez dire un champ privé B> ... alors c'est juste une erreur de codage. Vous pourriez aussi bien demander "Comment ça va (vrai) {}" abusé? Vous pouvez avoir des auto-accessoires privés, si vous voulez vraiment ...