7
votes

Isreadonly vous interdit-t-il d'un objet ilist personnalisé?

remarques pour ilist.isReadonly indique les éléments suivants:

Une collection en lecture seule ne permet pas l'addition, la suppression ou la modification des éléments après la création de la collecte.

Cela signifie-t-il qu'une classe personnalisée implémente IList ne peut pas ajouter ou supprimer des éléments interne ou ne veut-il simplement interdire à les utilisateurs de le faire à l'aide de l'interface Mibrods?

Si des modifications internes sont autorisées, cela signifie-t-il que le code qui s'attend à un IList avec ISReadonly vrai pour ne jamais changer est intrinsèquement cassé?

Si des modifications internes ne sont pas autorisées, cela signifie-t-il qu'il est impossible d'écrire un valide qui peut changer en interne, mais permettre aux utilisateurs de le modifier?


0 commentaires

3 Réponses :


4
votes

Code interne peut effectivement le changer.

Le ISReadonly code> indique que la liste ne peut pas être modifiée directement via cette interface. p>

Je conviens que "le code qui s'attend à ce que" Code> IList code> avec ISReadonly code> VRAI pour ne jamais changer est intrinsèquement brisé ". p>

Microsoft a introduit le immutableliste code> classe, et c'est peut-être ceci est l'une des raisons. p>

ireadonlist code> à la rescousse? ER, Malheureusement Non: P>

Console.WriteLine(shouldBeReadOnly.IsReadOnly);  // Readonly? Yep! This prints True.
Console.WriteLine(shouldBeReadOnly[0]);    // Prints 1.
Console.WriteLine(shouldBeReadOnly.Count); // Prints 1.
test[0] = 2;
test.Add(-1);
Console.WriteLine(shouldBeReadOnly[0]);    // Prints 2. Oops. It wasn't readonly at all.
Console.WriteLine(shouldBeReadOnly.Count); // Prints 2.


13 commentaires

Ici, vous modifiez la valeur de la liste "plaine", pas la seule. Il suffit de l'affecter à une ironlyliste ne le rendra pas réadapté.


@ Balázs Le point est que vous ne pouvez pas compter sur une liste réadonnée étant immuable (qui est la question dans le PO).


@ Balázs Ceci, d'une certaine manière, était ma question. Donc, il a raison sur le point.


Je dis que en faisant cela: iReadonlist loadonly = Test; Vous ne faites pas la liste en lecture seule. Comme cela, vous n'abandonnez qu'une référence d'objet à un autre. Cette affectation ne définira pas la propriété iSreadonly sur true . Au lieu de cela, il empêchera la mutation en caché ajouter () et d'autres membres, si vous l'avez fait: readonly.add (8) Cela n'aurait pas compilé. En dehors de cela, vous avez essayé de modifier la valeur comme: Readonly [0] = 98; Cela entraînerait également une erreur de compilateur, car il n'y a pas de seigur défini sur l'indexeur,


Et comme note latérale, je n'ai jamais vu personne exposant une collection intégrable en tant que liste. C'est pourquoi ienumerable existe; Après l'après-vente, ce n'est pas l'affaire du code extérieur d'accéder aux éléments par index ou même avoir une idée de la structure utilisée par la classe contenant des éléments de maintien.


@Matthewwatson ouais, peut-être que je fais. (pas de sarcasme)


@ Balázs Je vais expliquer un peu plus: la question est la suivante: une méthode qui reçoit un paramètre de type IList avec isreadonly défini sur true suppose que la liste suppose que la liste est immuable? Ou une méthode qui reçoit un paramètre de type IreadonlyList suppose que la liste est immuable et ne changera jamais? Et la réponse à ces deux est: "Non, il ne peut pas".


Je viens de remarquer que iReadonlist est pas implémente ilist . Donc Ireadonlist Ne fait jamais une affirmation selon laquelle elle ne sera pas modifiée après la construction. Il n'a pas non plus de propriété iSreadonly .


@Relatiny_Random Ireadonlist n'était qu'un autre exemple d'une classe qui est réadonnée mais non immuable. Mais voir mon autre exemple en utilisant list .AsReadonly () qui renvoie une liste de réadonner mutable externe.


@ Balázs "Je n'ai jamais vu personne qui expose une collection inhumée en tant que liste" - ce n'est pas ce que nous discutons. Nous parlons de collections réadonnées qui sont mutables.


@Matthewwatson Oui, je suis d'accord avec cela, mais j'approchai la question d'un côté technique plutôt que de la théorie. Mais étant réadonnant! = Être immuable. Si vous écrivez une classe qui contient des propriétés réadonnées, c'est une instance d'une autre classe, vous pouvez muter le contenu contenu. Vous ne pouvez tout simplement pas changer c'est une référence. Il y a une différence conceptuelle entre les deux.


@Matthewwatson Ok, alors je vais juste traiter celui-ci comme un malentendu :)


Je suis d'accord avec Jon Hanna et Matthew Watson sur le Readonlycollection dans le cadre comme exemple de collection qui se déclare en lecture seule mais n'est pas immuable. Cependant, la documentation de la propriété iList.Readonly est différente du ReadonlyCollection .List.Readonly Documentation en ce que ce dernier définit une collection en lecture seule en lecture -Elly wrapper autour d'une collection ordinaire, alors que le premier ne fait aucune présomption de ce type.



1
votes

une classe implémentation ilist avec isreadonly == true promet qu'il ne change pas, à la fois en interne et de l'extérieur, après avoir été créé. Bien sûr, il appartient à la mise en œuvre de garder cette promesse. S'il échoue, la mise en œuvre du IList est cassée, pas le code à l'aide de celui-ci.

On peut affirmer que cela ne devrait contenir que pour une implémentation d'interface explicite. Je voudrais toujours envisager une telle mise en œuvre comme cassée.


3 commentaires

En d'autres termes, vous croyez qu'il est impossible d'écrire un iList modifié (code> avec iSreadonly true?


Je pense qu'il est vrai que ce ne serait pas une mise en œuvre valide.


Cela ne promet aucune chose. Ceci est totalement en désaccord avec la documentation et les implémentations fournies par le cadre.



5
votes

https://msdn.microsoft. com / fr-nous / bibliothèque / cc645181% 28v = vs.110% 29.aspx

une collection en lecture seule est simplement une collection avec une enveloppe qui empêche la modification de la collection; Par conséquent, si des modifications sont apportées à la collection sous-jacente, la collection en lecture seule reflète ces changements.

Pour un autre type, il n'y a rien à vous empêcher d'exposer une collection vraiment immuable comme ilist avec cette propriété renvoyant vrai, mais vous n'êtes pas obligé.

Nous pouvons également voir que les cas de la bibliothèque-cadre qui retourne true pour isreadonly permettent souvent de muté de la collection interne. xxx

Vraiment, isreadonly vous indique que les méthodes de mutation telles que ajoutent et que le côté Setter de l'indexeur échouera, non pas que l'objet est immuable à tous les moyens. < P> Une considération intéressante à cet égard: Certains endroits dans les bibliothèques-cadres ont eux-mêmes besoin de listes en lecture seule qui sont vraiment en lecture seule. Leur interface publique renvoie soit loadonlycollection ou ireadonlist (par exemple blockexpression.expressions retours Readonlycollection ) Mais ils ne font pas confiance aux collections en lecture seule. Ils utilisent un type interne appelé truereadonlycollection créé comme une enveloppe d'une matrice fraîche, copié sur la construction, de sorte que rien d'autre ne puisse le changer. Ce type est confié à ne jamais changer et peut donc être partagé entre les utilisations, mais tous les autres cas ne sont pas.


1 commentaires

@ Андрейбеньковский Oui, deux façons différentes de le phraser dans ma tête quand je l'ai écrite et j'ai fini par taper une méonnade des deux :)