views:

73

answers:

1

I'm writing a class to represent a Pivot Collection, the root object recognized by Pivot. A Collection has several attributes, a list of facet categories (each represented by a FacetCategory object) and a list of items (each represented by a PivotItem object). Therefore, an extremely simplified Collection reads:

public class PivotCollection
{
    private List<FacetCategory> categories;
    private List<PivotItem> items;
    // other attributes
}

What I'm unsure of is how to properly grant access to those two lists. Because declaration order of both facet categories and items is visible to the user, I can't use sets, but the class also shouldn't allow duplicate categories or items. Furthermore, I'd like to make the Collection object as easy to use as possible. So my choices are:

  1. Have PivotCollection implement IList<PivotItem> and have accessor methods for FacetCategory: In this case, one would add an item to Collection foo by writing foo.Add(bar). This works, but since a Collection is equally both kinds of list making it only pass as a list for one type (category or item) seems like a subpar solution.

  2. Create nested wrapper classes for List (CategoryList and ItemList). This has the advantage of making a consistent interface but the downside is that these properties would no longer be able to serve as lists (because I need to override the non-virtual Add method I have to implement IList rather than subclass List. Implicit casting wouldn't work because that would return the Add method to its normal behavior.

Also, for reasons I can't figure out, IList is missing an AddRange method...

public class PivotCollection
{
    private class CategoryList: IList<FacetCategory>
    {
        // ...
    }

    private readonly CategoryList categories = new CategoryList();
    private readonly ItemList items = new ItemList();

    public CategoryList FacetCategories
    {
        get { return categories; }
        set { categories.Clear(); categories.AddRange(value); }
    }

    public ItemList Items
    {
        get { return items; }
        set { items.Clear(); items.AddRange(value); }
    }
}

Finally, the third option is to combine options one and two, so that PivotCollection implements IList<PivotItem> and has a property FacetCategories.

Question: Which of these three is most appropriate, and why?

+2  A: 

The best thing to do here is to create your own collection class that inherits System.Collections.ObjectModel.Collection<T> and overrides InsertItem.

SLaks