2009-07-02 5 views
8

Ich schreibe eine Array-Wrapper-Klasse, die IList<T> implementiert. Ich bin mir nicht sicher, was ich für IList<T>.IsReadOnly (geerbt von ICollection<T>), obwohl.Vertrag von ICollection <T> .IsReadOnly

Meine Klasse verbietet das Einfügen und Entfernen. Es ermöglicht ermöglichen, Elemente über die this[int].set Eigenschaft zu ändern.

Die MSDN besagt, dass

Eine Sammlung, die schreibgeschützt ist, erlaubt es nicht, die Hinzufügen, Entfernen oder Modifikation von Elementen nach der Sammlung erstellt wird.

Für meine Klasse, dies scheint zu implizieren, dass ich true zurückkehren, aber in meinen Augen das macht die Eigenschaft eine Bit völlig nutzlos: soweit ich sehen kann, ist die Anwendung dieses Verfahrens wird wie folgt :

Die Clients behandeln eine beliebige IList und müssen ein Element einfügen, , wenn überhaupt möglich. Sie können dies tun, indem Sie einfach Insert aufrufen und die resultierende NotSupportedException fangen - und aus verschiedenen Gründen kann dies nicht wünschenswert sein. Anstatt eine Ausnahme zu provozieren, können die Kunden die Eigenschaft IsReadOnly vorab testen.

Aber das Ergebnis dieser Eigenschaft wird falsch sein, weil es Modifizierbarkeit der Sammlung mit Modifizierbarkeit seines Inhalts mischt - die völlig unabhängig Angelegenheiten sind!

Um sicher zu sein, gibt es die IList.IsFixedSize Eigenschaft, aber dies ist ein separater Typ (IList<T> tut nichtIList verlängern). Was soll ich machen? Implementieren Sie auch IList (ich wirklich nicht wie diese Alternative)? Mach etwas anderes?

+1

Nur etwas hinzufügen, mit Readonlycollection der Inhalt kann veränderbar (wenn wandelbar) und immer noch sein, die „IsReadOnly“ Eigenschaft gibt wahr ... –

+0

@bruno -, die von „Bearbeitung Inhalt“ Sie bedeuten, davon abhängt, ob ** ersetzen ** das Element an einer bestimmten Position (Liste [n] = Element) und ** das Element an einer bestimmten Position mutieren (Liste [n] .SomeProp = Wert). –

Antwort

2

Etwas anderes ...

Ihre Sammlung zu prüfen, ist ein Wrapper-Array und es hat einige Array-ähnliche Semantik. dh Elemente können nicht eingefügt oder entfernt werden, aber sie können geändert werden.

Arrays zurückgeben false für IsReadOnly und true für IsFixedSize.

Ich glaube, ich wahrscheinlich IList zusätzlich zu IList<T> implementieren würde und imitieren dann das Array Verhalten, soweit IsReadOnly und IsFixedSize betroffen sind.

Das Schlüsselwort in den remark from MSDN ist die „oder“:

Eine Sammlung, die schreibgeschützt ist, erlaubt es nicht, die Hinzufügen, Entfernen, oder Modifikation von Elementen nach der Sammlung erstellt wird.

Ihre Sammlung tut Modifikation erlauben würde so Rückkehr true für IsReadOnly diesen Vertrag brechen werden, meiner Meinung nach.

+0

Wichtig: Ein Array gibt 'false' zurück, wenn Sie die öffentliche Eigenschaft 'IsReadOnly' aufrufen. Diese öffentliche Eigenschaft ist auch die Implementierung von "IList.IsReadOnly" auf der *** nicht-generischen *** Schnittstelle "IList". Wenn das Array ein "Vektor" ist, d. H. Es ist eindimensional und ausgehend von Index 0 wie "normale" Arrays, implementiert das Array auch die generische Schnittstelle "IList <>". Dann erbt die generische Schnittstelle "IList <>" ein "IsReadOnly" von "ICollection <>". Diese 'ICollection <>. IsReadOnly' wird mit einer Art" magischer "expliziter Schnittstellenimplementierung implementiert. Diese Implementierung ist wahr! –

+1

Ein Beispiel: 'int [] arr = {2, 4, 6,}; bool x = arr.IsReadOnly;/* falsch */bool y = ((IList ) arr) .IsReadOnly; /* wahr! */'Wenn der Fragesteller sich wie ein Array verhalten will, sollte er' true' für die Implementierung der _generic_ Schnittstelle zurückgeben. –

2

Ich denke, um den Vertrag wie definiert zu erfüllen, müssten Sie true zurückgeben.

Sie könnten (zusätzlich) IBindingList implementieren - das hat AllowNew, AllowEdit und AllowRemove. Sie würden zurückkehren true von AllowEdit und false aus den beiden anderen.

Ob der Anrufer dies überprüft, liegt jedoch beim Anrufer. Eine Menge von UI-Bindungscode wird jedoch.

hinzugefügt:

Auch; Sie sollten wahrscheinlich IList implementieren, wenn Sie IList<T> implementieren; insbesondere ist IList für eine Reihe von Reflexions- und Bindungsszenarien wichtig, bei denen die Typen nicht im Voraus bekannt sind.

+0

Danke - Ich habe (wieder einmal) die Bindung völlig vergessen (ich benutze sie nicht sehr oft). Ich werde deinem Rat folgen. –

1

Hier ist die Semantik der Modifikation wichtig. Es besteht ein Unterschied zwischen dem Ändern der Elemente einer Sammlung und dem Ändern der Objekte, die in der Sammlung enthalten sind. Denken Sie an die Elemente der tatsächlichen Räume in der Sammlung. Sie können keine Leerzeichen hinzufügen, Leerzeichen entfernen oder das Objekt in einem bestimmten Bereich ändern. Das ist der Vertrag, den IsReadOnly hält.