views:

204

answers:

3

I'm writing an array wrapper class that implements IList<T>. I’m unsure of what to return for IList<T>.IsReadOnly (inherited from ICollection<T>), though.

My class disallows insertion and removal. It does allow modifying items via the this[int].set property.

The MSDN states that

A collection that is read-only does not allow the addition, removal, or modification of elements after the collection is created.

For my class, this seems to imply that I have to return true but in my eyes this renders the property a bitcompletely useless: as far as I can see, the use of this method is as follows:

The clients handle an arbitrary IList and need to insert an element into it, if at all possible. They can do this by just calling Insert and catching the resulting NotSupportedException – and for various reasons, this may not be desirable. So instead of provoking an exception, the clients can just test the IsReadOnly property beforehand.

But the result of this property will be wrong because it mixes modifiability of the collection with modifiability of its contents – which are completely unrelated matters!

To be sure, there’s the IList.IsFixedSize property but this is a separate type (IList<T> does not extend IList). What should I do? Also implement IList (I really don’t like this alternative)? Do something else?

+2  A: 

I think that to meet the contract as defined, you would have to return true.

You could (additionally) implement IBindingList - this has AllowNew, AllowEdit and AllowRemove. You would return true from AllowEdit, and false from the other two.

Whether your caller checks for this is up to the caller, though. A lot of UI binding code will, though.

added:

Also; you should probably implement IList if you are implementing IList<T>; in particular, IList is important for a number of reflection and binding scenarios, where the types aren't known ahead of time.

Marc Gravell
Thanks – I (once again) completely forgot about binding (I don’t use it very often). I’ll follow your advice.
Konrad Rudolph
+1  A: 

Something else to consider...

Your collection is an array wrapper and it has some array-like semantics. ie, Items can't be inserted or removed but they can be modified.

Arrays return false for IsReadOnly and true for IsFixedSize.

I think I would probably implement IList in addition to IList<T> and then mimic the array behaviour, so far as IsReadOnly and IsFixedSize are concerned.

The key word in the remark from MSDN is the "or":

A collection that is read-only does not allow the addition, removal, or modification of elements after the collection is created.

Your collection does allow modification, so returning true for IsReadOnly would be breaking that contract, in my opinion.

LukeH
A: 

Here, the semantics of modification are important. There is a difference between modifying the elements of a collection and modifying the objects contained by the collection. Think of the elements of the actual spaces in the collection. You can't add spaces, remove spaces, or change the object in a certain space. That's the contract that IsReadOnly abides by.

Marcus Griep