tags:

views:

295

answers:

1

Is there any better/nicer way to do the following?

  • An object that can either be used as a normal object and access it's properties and/or as an IEnumerable collection of the object. See code below:

Sample:

static void Main(string[] args)
{
    Item i = new Item() {Name="Erik"};
    i.Add(new Item() {Name="Fred"});
    i.Add(new Item() {Name="Bert"});

    // First access the object as collection and foreach it
    Console.WriteLine("=> Collection of Items");
    foreach (Item item in i)
        Console.WriteLine(item.Name);

    // Access a single property on the object that gives back the first element in the list.
    Console.WriteLine("=> Single Item");
    Console.WriteLine(i.Name);

    Console.ReadLine();
}


public class Item : IEnumerable<Item>
{
    public void Add(Item item)
    {
        _items.Add(item);
        UpdateInnerList();
    }

    #region Fields

    private List<Item> _items = new List<Item>();
    private List<Item> _innerList = new List<Item>();           
    private string _name = string.Empty;

    #endregion

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            UpdateInnerList();
        }
    }

    #region Methods

    public IEnumerator<Item> GetEnumerator()
    {
        return _innerList.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _innerList.GetEnumerator();
    }

    private void UpdateInnerList()
    {
        _innerList.Clear();
        _innerList.Add(this);
        _innerList.AddRange(_items);
    }

    #endregion
}
+2  A: 

That looks a lot like a Tree, although I usually model this more explicitly with a Tree class like this one:

public class Tree<T>
{
    public T Item { get; set; }

    public IList<T> Children { get; }
}

Your code seems like a combination of a Tree and a Composite, although you are not quite there since the enumerator doesn't include the 'root' item.

The design, at it is currently presented, seems slightly off. I would either pull it more in the direction of an explicit Tree like above, or towards a true Composite.

Mark Seemann
What I would like to be able to do is: <%= Object["Products"].Name %> or do <% foreach(Object o in Object["Products"]) { %> <li><%= o.Name %></li><% } %>, which is not possible if it's in a tree form, but it might be that idea I want to accomplish is wrong.
erik
Sounds like you just need a Dictionary, then...
Mark Seemann