C # объект, который можно использовать как IEnumerable и одиночный объект - PullRequest
2 голосов
/ 15 февраля 2010

Есть ли лучший / лучший способ сделать следующее?

  • Объект, который можно использовать как обычный объект и получить доступ к его свойствам и / или как коллекцию объекта IEnumerable. Смотрите код ниже:

Пример:

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 ]

2 голосов
/ 15 февраля 2010

Это очень похоже на дерево, хотя я обычно моделирую это более явно с классом дерева, подобным этому:

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

    public IList<T> Children { get; }
}

Ваш код выглядит как комбинация дерева и Composite , хотя вы не совсем там, так как перечислитель не включает элемент 'root'.

Дизайн, представленный в настоящее время, выглядит немного не так. Я бы либо потянул его больше в направлении явного Дерева, как указано выше, либо в направлении истинного Композита.

0 голосов
/ 20 февраля 2012

Вы имели в виду что-то подобное?

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleTestCSharp
{
    class Node : IEnumerable<Node>
    {
        public string Name { get; private set; }
        private List<Node> _list = new List<Node>();

        public Node(string name)
        {
            Name = name;
        }

        public void Add(Node child)
        {
            _list.Add(child);
        }

        public Node this[string name]
        {
            get
            {
                return _list.First(el => el.Name == name);
            }
        }

        public IEnumerator<Node> GetEnumerator()
        {
            return _list.GetEnumerator();
        }

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

        public override string ToString()
        {
            return Name;
        }
    }   

    class Program
    {

        static void Main(string[] args)
        {
            var root = new Node("root");
            root.Add(new Node("1st child"));
            root.Add(new Node("2nd child"));
            root.Add(new Node("3rd child"));

            var firstchild = root["1st child"];

            foreach (var child in root)
            {
                Console.WriteLine(child);
            }
        }
    }
}
...