Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Contract of ICollection<T>.IsReadOnly

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?

like image 609
Konrad Rudolph Avatar asked Jul 02 '09 09:07

Konrad Rudolph


2 Answers

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.

like image 106
LukeH Avatar answered Sep 21 '22 01:09

LukeH


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.

like image 25
Marc Gravell Avatar answered Sep 21 '22 01:09

Marc Gravell