7
votes

Types de référence Readonly immuables et violation FXCOP: Ne déclarez pas lire les types de référence mutable

J'ai essayé d'envelopper ma tête autour de cette violation FXCop "DonotdeclaReeadonlyMutaBereFerencePetypes"

MSDN: http://msdn.microsoft.com/en-us/library/ms182302%28vs.80%29.aspx

code de MSDN Ce qui causerait cette violation: xxx

de jon's réponse ici et Ici , je comprends que le champ contenant la référence à l'objet (dans ce cas somestringingbuilder) est réadon et non l'objet lui-même (qui est créé par nouveau StringBuilder () ) < / P>

Ainsi, en prenant cet exemple, comment puis-je modifier l'objet lui-même, une fois que le champ en a une référence? J'aime Eric Lippert's Exemple de la manière dont le tableau de réadonnement peut être modifié et souhaite voir quelque chose de similaire pour tout autre type de référence mutable


0 commentaires

5 Réponses :


0
votes

.NET a une liste de types de référence immuables autorisés ici, stringbuilder n'est pas l'un d'entre eux.

La plainte est que ce que vous construisez n'est pas immuable, bien que le constructeur statique soit appelé une fois et que la classe est initialisée une fois, c'est tout ce qui reste le même, le reste est mutable. Un thread peut appeler .append () , puis une autre ... Vous voyez comment le générateur de cordes elle-même mutait et n'est pas vraiment lisonly , car il change constamment des états / mutatatures .

la déclarant Readonly est vraiment un abu car l'objet référencé là-bas est en constante évolution.


1 commentaires

Sinon, comment faire une distinction entre un champ de type de référence qui pointera toujours sur le même objet et qui peut indiquer différents objets pendant la durée de vie de l'objet contenant? Quelqu'un qui ne comprend pas quels types de référence sont peut-être confondus, mais une telle personne est susceptible d'être confondue sur de nombreuses choses à moins que ou jusqu'à ce qu'il apprend à comprendre les types de référence.



0
votes

Vous ne pouvez pas modifier la référence, mais tout appel de l'objet (mutable) change son état.

Par conséquent, depuis que le somestringingBuilder (dans cet exemple) est mutable lui-même, son contenu peut changer, ce qui peut être trompeur pour les utilisateurs de la classe car il n'est donc pas vraiment "en lecture seule".

Fondamentalement, Readonly ne garantit en aucun cas que l'objet des ennemis ne change pas, il distrait simplement que la référence ne change pas.


1 commentaires

Le fait qu'une référence ne change pas peut être essentielle à d'autres parties du code (par exemple, un autre objet peut saisir une référence au StringBuilder et s'attendre à pouvoir saisir sa valeur); Alors qu'il convient certainement de savoir que l'objet référencé peut être muté, cela n'implique pas qu'il existe quelque chose d'inutile de déclarer la référence elle-même immuable. BTW, même les délégués ne sont pas toujours immuables; Un délégué formé à partir d'un mutateur de structure va encadrer la structure et la structure en boîte sera mutable.



3
votes

Comme la classe MutaBereFerenceCetyTypes est présentée dans la question, vous ne pouvez pas vraiment la muter de tout appelant extérieur depuis que le champ SomestringBuilder est privé.

Cependant, la classe elle-même pourrait muté le champ. Ce n'est pas actuellement, mais il pourrait dans une itération ultérieure.

Voici un exemple de méthode: xxx

appelera la méthode de la mutation, car SomestringingBuilder aura maintenant changé.

Immutabilité ne concerne pas uniquement l'incarnation actuelle de votre code, mais également de vous protéger des futures erreurs. Pas que toutes les classes doivent être immuables, mais il est le plus sûr de rester cohérent si vous choisissez de créer un type immuable.


2 commentaires

Juste une petite erreur: le champ est protégé , pas privé, il est donc absolument mutable de l'extérieur. Je suppose que ceci est ce que FXCop s'oppose.


@Konrad Rudolph: bonne prise! Je viens de regarder le premier mot-clé et remarqua que ce n'était pas un modificateur d'accès, et doit donc avoir défaut à la valeur par défaut (SIC). Je n'ai pas remarqué que les mots-clés avaient été commutés.



0
votes

Vous ne changeriez pas la valeur de l'objet. C'est le point de la règle. Tout champ déclaré comme réadonnement devrait en infriter, que ce soit, réadonn. Avoir une référence mutable réadonnée est un oxymoron. Si vous pouvez modifier la valeur de ce que le champ "Points" à ce moment-là, ce n'est plus vraiment réadonn. Il n'y a vraiment aucune différence fonctionnelle entre l'attribution de la valeur de tous les membres d'un objet A à un objet B représenté par un champ ou simplement l'affectation d'un à ce champ (lorsqu'il est du même type), mais un seul d'entre eux est valable lorsque le champ est déclaré être réadonnée, mais puisque vous pouvez effectivement chérer la valeur de ce qui est représenté par le champ, il est comme déjà indiqué, pas vraiment réellement lison


0 commentaires

6
votes

Readonly signifie que vous ne pouvez pas changer La post-construction de référence.

La position officielle FXCOP est qu'elle recommande que seuls les types qui ne peuvent pas être modifiés doivent être déclarés Readonly . Par conséquent, quelque chose comme une chaîne est correct car la valeur de l'objet ne peut pas être modifiée. Toutefois, la valeur de stringbuilder peut modifier mais le permettant de le rendre readonly ne vous empêche d'attribuer le champ à un autre stringbuilder instance ou null après la course du constructeur .

Je suis en désaccord avec FXCop sur cette règle. Tant que l'on comprend que ceci est simplement une exécution que la référence ne peut pas changer post-construction, il n'y a pas de confusion.

Notez que les types de valeur sont rendus immuables par le loadonly mots clés mais les types de référence ne sont pas. xxx


2 commentaires

+1 pour le code. Relier votre code dans MSDN. Aurait marqué la vôtre comme réponse si vous avez répondu plus tôt. Bonne quand même !!


Ancienne réponse, mais toujours très pertinente. L'analyse de code (comme il est maintenant) a toujours des règles stupides (telles que celle-ci) qui supposent que les codeurs sont des idiots. Quiconque comprend même la moitié de la langue sait que lisonly signifie. La première chose que je fais lors de la mise en place d'un nouveau projet est désactivée une tonne de règles de CA telles que CA2104.