We use collections all the time. Many times we have to expose them to users of our classes. Lets look at this simple tree node class:

class TreeNode
{
    private List<TreeNode> children = new List<TreeNode>();        

    public IList<TreeNode> Children
    {
        get { return children; }
    }
}

The children need to be accessed by who ever uses our TreeNode, but are they allowed to add new tree nodes to the collection? Not necessarily. We might want to control it inside the TreeNode class. So how to expose the children as read only? very simple, use the ReadOnlyCollection class.

The ReadOnlyCollection is simply a read only wrapper to the collection, that prevents modifying the original collection. It does not create new objects but holds the original collection, so any changes to the original collection will be reflected in the read only collection. The ReadOnlyCollection implements few interfaces: IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable. The implementation is straight forward: for every function that changes the original collection an exception is thrown, otherwise return the result of calling the same function on the original collection.

The List<T> has a AsReadOnly method that will simply returns the read only wrapper of the current collection.

Lets see the safe version of the TreeNode:

class TreeNode
{
    private List<TreeNode> children = new List<TreeNode>();        

    public IList<TreeNode> Children
    {
        get { return children.AsReadOnly(); }
    }
}

So its very easy to expose collections as read only, why don’t you do it?

Tags :

11 Responses to “How to Expose Your Collections Safely”


  1. Poul

    Said on April 10, 2008 :

    ReadOnlyCollection is great, but only enforces readonly at runtime, exposing collections as IEnumerable enforces readonly at compiletime.

    And if you for some reason needs to use the indexer, simply use new List(collection)

  2. Shahar A

    Said on April 10, 2008 :

    I Agree if you can work with IEnumarable its even better. However, if you create new List(collection) objects will be copied into the new list, and new list can be change with no reflection to the original one which might be dangarous…

  3. Yaswanth

    Said on April 10, 2008 :

    Is there any similar this in Java ?

  4. Yaswanth

    Said on April 10, 2008 :

    Is there any similar thing in JAVA ?

  5. Judah

    Said on April 10, 2008 :

    I agree with Poul, exposing as IEnumerable is best, since it gives you compile-time verification. Also, list.AsReadOnly actually allocates a new object behind the scenes, exposing as IEnumerable does not.

  6. Will

    Said on April 10, 2008 :

    Probably because its not always appropriate.

  7. Kit Anderson

    Said on April 11, 2008 :

    @Yaswanth, it would be possible to create your own wrapper, extending the collection you wish to protect, and re implement the ‘write’ functions to throw exceptions, while the ‘read’ functions can call the original parent class functions.

  8. Ben

    Said on April 11, 2008 :

    Yes, java.util.Collections introduced this into the language about a decade ago.

3 Trackback(s)

  1. Apr 11, 2008: Reflective Perspective - Chris Alcock » The Morning Brew #71
  2. Apr 11, 2008: Dew Drop - April 11, 2008 | Alvin Ashcraft's Morning Dew
  3. Apr 18, 2008: igorbrejc.net » Friday Goodies - 18. March

Post a Comment