8
votes

Contrat d'icollection .isReadonly

J'écris une classe d'emballage de tableau qui implémente ilist . Je ne suis pas sûr de ce qu'il faut revenir pour ilist .isReadonly (hérité de icollection ), cependant.

Mon classes désactive l'insertion et l'enlèvement. Il est autorise modifier des éléments via le ceci [int] .set .Setre propriété.

Le MSDN stipule que

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.

Pour ma classe, cela semble impliquer que je dois retourner vrai mais dans mes yeux, cela rend la propriété A Bit complètement inutile: autant que je puisse voir , l'utilisation de cette méthode est la suivante:

Les clients gèrent un arbitraire et doivent insérer un élément dans celui-ci, si possible . Ils peuvent le faire en appelant simplement insérer et attraper le notsupportedexception résultant - et pour diverses raisons, cela peut ne pas être souhaitable. Ainsi, au lieu de provoquer une exception, les clients peuvent simplement tester la propriété IsReadonly à l'avance.

Mais le résultat de cette propriété sera faux car il mélange la modification de la collection avec la modification de son contenu - qui sont compatibles entièrement indépendants ! ! !

Assurez-vous, il y a la propriété iList.FeCixedSeize mais ceci est un type distinct ( ilist pas étendre Ilist ). Que devrais-je faire? Également implémenter ilist (je ne pas comme cette alternative)? Faire quelque chose d'autre?


2 commentaires

Juste pour ajouter quelque chose, avec Readonlycollection Le contenu peut être modifiable (si mutable) et toujours, la propriété "Isreadonly" retourne vrai ...


@bruno - qui dépend si par "édition de contenu", vous voulez dire Remplacement de l'élément à une position donnée (liste [N] = élément) et mutation l'élément à une donnée position (liste [n] .SomeProp = valeur).


3 Réponses :


2
votes

Je pense que pour répondre au contrat tel que défini, vous devez retourner vrai .

Vous pouvez (en outre) implémenter ibindinglist - ceci a ALOWOWEW , autorisé et allowremove . Vous retourneriez true à partir de autorisé , et false à partir des deux autres.

Si votre appelant vérifie cela est à la hauteur de l'appelant. Un nouveau code de liaison UI sera cependant.

ajouté:

aussi; vous devriez implémenter probablement iList si vous implémentez ilist ; En particulier, IList est important pour un certain nombre de scénarios de réflexion et de liaison, où les types ne sont pas connus à l'avance.


1 commentaires

Merci - I (encore une fois) complètement oublié de la liaison (je ne l'utilise pas très souvent). Je suivrai vos conseils.



2
votes

Quelque chose d'autre à considérer ...

Votre collection est un wrapper de tableau et il possède une sémantique semblable à une matrice. C'est-à-dire que les éléments ne peuvent pas être insérés ou supprimés, mais ils peuvent être modifiés.

Arrays retour false pour isreadonly et true pour isfixedSize . .

Je pense que je voudrais probablement mettre en œuvre iList en plus de ilist puis imitez le comportement de la matrice, jusqu'à présent isreadonly et isfixedSize est concerné.

Le mot clé dans le remarque de MSDN est le " ou ":

Une collection qui est en lecture seule ne permet pas l'addition, le retrait, ou Modification des éléments après la création de la collection.

Votre collection est la modification, donc retourner true pour isreadonly enfreindrait ce contrat, à mon avis.


2 commentaires

IMPORTANT: un tableau renvoie false si vous appelez le public iSReadonly propriété. Cette propriété publique est également la mise en œuvre de ilist.isReadonly sur l'interface non générique IList . Si le tableau est un "vecteur", c'est un "vecteur", il est unidimensionnel et commence à partir d'index 0 comme des tableaux "ordinaires", le tableau implémente également l'interface générique IList <> . Ensuite, l'interface générique IList <> hérite d'un isreadonly de icollection <> . Ce Icollection <>. ISReadonly est mis en œuvre avec une sorte de mise en œuvre de l'interface explicite "magique". Cette mise en œuvre revient vrai!


Un exemple: int [] arr = {2, 4, 6,}; bool x = arr.isReadonly; / * FALSE * / BOOL Y = ((IList ) Ar) .isReadonly; /* vrai! * / Donc, si l'astucieux veut se comporter comme un tableau, il devrait retourner vrai pour la mise en œuvre de l'interface générique .



1
votes

Ici, la sémantique de modification est importante. Il existe une différence entre modifier les éléments d'une collection et modifier les objets contenus par la collection. Pensez aux éléments des espaces réels de la collection. Vous ne pouvez pas ajouter d'espaces, supprimer des espaces ou changer l'objet dans un certain espace. C'est le contrat que isreadonly abie.


0 commentaires