Partilhar via


Any chance of an IReadOnlyList collection interface? [Kit George]

Joe White asked for this specific feature:

For the most part, I like the way you designed collections in .NET -- especially interfaces like IEnumerable, ICollection, and IList. The problem is, you jump straight from a read-only, non-random-access collection (ICollection) to a read/write, random-access collection (IList). Very often, it would be useful to have something in between -- a read-only, but still random-access, list, with a read-only indexer but without some of the methods like Add, Clear, Remove, etc. Ideally IReadOnlyList would descend from ICollection, and IList would then descend from IReadOnlyList. Any chance something like this could make it into a future version of the Framework?

Because we could provide a default implementation for what you're talking about Joe, rather than giving you an interface, we provided ReadOnlyCollectionBase. However, given that it wasn't strongly typed, I can understand a reluctance to use it. But with the introduction of generics, we now also have ReadOnlyCollection<T>, so you get the same functionality, but strongly-typed: awesome!

ReadOnlyCollection<T> isn't sealed, so feel free to write your own collection on top if needed. We have no plans to introduce an interface for this same concept, since the collections we've made for this suit the general need.

Comments

  • Anonymous
    January 19, 2004
    This is a newbie question but I'm confused. Why isn't the ReadOnlyCollection strongly typed? I have a class that inherits from ReadOnlyCollection and I can use it w/o doing lots of unecessary casting.
  • Anonymous
    January 20, 2004
    sigh

    So close, yet so far. Why not give us an interface and a default implementation? If I decide that it'd be better to define a certain property as an interface and not a class, I'm not going to change my mind just because the appropriate interface hasn't been included in the BCL. In this case, I'll just end up defining an IReadOnlyList equivalent myself, and that means more code and more documentation that I have to write, and one more type that the guy using my library is going to have to wrap his brain around.

    The more I learn about the new collections, the more I realize that they really aren't going to do much for me. For example, most of the work I do with collections involves type-safe, modifiable types that do not have list semantics. That is, all I'm really looking for are Add(T), Contains(T), Clear, and Remove(T) methods on top of the ICollection<T> interface. Again, given a choice between defining my own types or making the jump to IList (with its extraneous members and list semantics), I'm going to choose the first choice every time. I understand that you need to think long and hard before adding a new type to the framework, but it seems like this is the kind of stuff you should be throwing at us by the handful.
  • Anonymous
    January 20, 2004
    More on my IReadOnlyList suggestion:

    I'm not looking for an implementation of a read-only list; I already use ReadOnlyCollectionBase extensively. I'm looking for an interface for read-only list access (whether the underlying list is read-only or not; it would be useful both ways).

    Let's say I write a method that sums all the numbers in a collection. (This is a trivial example; yes, IEnumerable would work perfectly well for this, but pretend that I really need the random access.) Sum() won't modify the contents of that collection (or shouldn't, anyway!), and I want to make that fact clear in the code. So I want to be able to make its method signature look like this:

    public static int Sum(IReadOnlyList<int> values);

    This would have several advantages:
    * IReadOnlyList<> doesn't have a setter for its indexer, and doesn't have Add(), Clear(), Insert(), Remove(), or RemoveAt() methods. So it would be a compile-time error if Sum did try to modify the collection.
    * Therefore, the above signature is intention-revealing. It's immediately clear to the caller that Sum() cannot modify the collection.
    * I can pass a List<int>, an int[], or an IntCollection (descended from CollectionBase) to this method.
    * I can also pass a ReadOnlyCollection<int> or a ReadOnlyIntCollection (descended from ReadOnlyCollectionBase).

    Currently, I can't achieve all of the above goals. If I need random access, my parameter type has to be either IList or a specific class. If I use ICollection, my method can't do random access into the collection. If I use IList, I lose the compile-time enforcement of read-only access, and I also lose the ability to pass a ReadOnlyCollectionBase for that parameter. (Sure, I can pass an IList with IsReadOnly = true, e.g. by calling ArrayList.ReadOnly(IList), but I'd much rather catch the bug at compile time.) And if I use ReadOnlyCollection<int> as my parameter type, I lose the ability to call that method with int[], ICollection<int>, and even List<int>.

    Does that help clarify where I'm coming from?
  • Anonymous
    January 20, 2004
    Joe, your idea is a great one, very similar to the concepts in STL. I too would like to see a logical, professional set of interfaces, like the STL. Many times I have needed a read-only specification exactly as you.
  • Anonymous
    January 20, 2004
    David, we change the ICollection<T> in Whidbey. It will include Add, Remove, Contains and a few other methods. This will make ICollection<T> useful.

    Joe, you will able to create a ReadOnlyCollection<T> easily in Whidbey. There will be some methods on Array and List<T> to return you a readonly adapter. In addition, Array will be implementing IList<T> in whidbey.
  • Anonymous
    January 21, 2004
    It may sound surprising, or not, but IList and IList<T> are our interfaces intended for read-only collections. They both have IsReadOnly Boolean property that should return true when implemented by a read-only collection. The reason we don’t want to add a purely read-only interface is that we feel it would add too much unnecessary complexity to the library. Note that by complexity, we mean both the new interface and its consumers.

    We feel that API designers either don’t care about checking the IsReadOnly property at runtime and potentially throwing an exception, in which case IList is fine, or they would like to provide a really clean custom API, in which case they explicitly implement IList and publicly expose custom tailored read-only API. The latter is typical for collections exposed form object models.

    Of course there are scenarios where IReadOnlyList<T> would be better. We just think it would be not that much better and there are not that many of these scenarios.

    That said, your input is very valuable as we have not ruled out adding such interface in the future. We just want to be very very careful. We are listening to the feedback and trying to weigh all the pros and cons.

    Thanks.
  • Anonymous
    January 26, 2004
    The comment has been removed
  • Anonymous
    June 07, 2009
    PingBack from http://greenteafatburner.info/story.php?id=4726