0 votes
in Programming by (1.9k points)

I have a simple class below, it has a property Pages of type IList.

There are some options to implement this property, it can be an Array or a Collection / List / even ReadOnlyCollection

public class Book
    {
        private string[] _pages;

        public Book(string[] pages)
        {
            _pages = pages;
        }

        public IList<string> Pages
        {
            get
            {
                return _pages;
                //return new Collection<string>(_pages);
                //return new List<string>(_pages);
                //return new ReadOnlyCollection<string>(_pages);
            }
        }
    }

At design time, I do not know which actions that its clients will use the property but choosing any option above will affect its clients.

If a client uses Book class as below

var book = new Book(new[] {"A", "B"});
var pages = book.Pages;
pages[0] = "A2";

Not all implementation options of the property Pages will work for the client.

Option 1: returning an Array for Pages // OK, it works

public IList<string> Pages
    {
        get
        {
            return _pages;
        }
    }

Option 2: returning a Collection for Pages // KO, it throws an exception NotSupportedException Collection is read-only

public IList<string> Pages
    {
        get
        {
            return new Collection<string>(_pages);
        }
    }

Option 3: returning a List for Pages // OK, it works

public IList<string> Pages
    {
        get
        {
            return new List<string>(_pages);
        }
    }

Option 4: returning a ReadOnlyCollection for Pages // KO, it throws an exception SystemException Collection is read-only

public IList<string> Pages
    {
        get
        {
            return new ReadOnlyCollection<string>(_pages);
        }
    }

I don't think it could be wrong on the client side. Could anyone please give some explanation and suggest a good type for the Page?

1 Answer

0 votes
by (2.4k points)

Another option would be to define your own collection type PageCollection for example and use it in your Book class. The advantage of this is, that you hide the detail of how the collection is implemented. Another advantage of this approach is, that you can provide "special" methods for the collection.

For example you could extend an existing collection (it may also be a good advise to create a custom class for Page, instead of using plain strings:

public class PageCollection : List<Page>
{
    // additional methods
}

You can also wrap an existing collection. This has the advantage that you have full controll over the methods you want to provide to the "user".

public class PageCollection : IEnumerable<Page>
{
    private List<Page> _innerCollection = new List<Page>();

    public void RipOut(IEnumerable<Page> pages)
    {
        foreach (var page in pages)
        {
            _innerCollection.Remove(page);
        }
    }

    // other methods

    public IEnumerator<Page> GetEnumerator()
    {
        return _innerCollection.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

Hope it work!

131 questions

117 answers

7 comments

378 users

Welcome to Todayask Q&A, where you can ask questions and receive answers from other members of the community.
...