C#可以用作IEnumerable和Single对象的对象

时间:2010-02-15 08:44:58

标签: c# ienumerable

有没有更好/更好的方法来执行以下操作?

  • 一个对象,既可以用作普通对象,也可以访问它的属性和/或作为对象的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 个答案:

答案 0 :(得分:2)

看起来很像一棵树,虽然我通常使用像这样的Tree类更明确地对它进行建模:

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

    public IList<T> Children { get; }
}

您的代码似乎是树和Composite的组合,但由于枚举器不包含“根”项,因此您不在那里。

目前呈现的设计似乎有些偏差。我要么在上面的显式树的方向上拉更多,要么朝向真正的复合材料。

答案 1 :(得分:0)

你的意思是这样吗?

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);
            }
        }
    }
}