实现IEnumerable到我的对象

时间:2013-01-16 14:24:46

标签: c# ienumerable ienumerator

  

可能重复:
  Implementing C# IEnumerable<T> for a LinkedList class

现在搜索网页几个小时后,我仍然无法理解IEnumerable / IEnumerator如何运作以及如何实施。

我从头开始构建了一个简单的LinkedList但现在我想为它实现IEnumerable所以我可以预先知道它。我该怎么做?

class Program
{
    LL myList = new LL();

    static void Main()
    {
        var gogo = new Program();
    }
    public Program()
    {

        myList.Add("test");
        myList.Add("test1");

        foreach (var item in myList) //This doesn't work because I havn't implemented Ienumerable
            Console.WriteLine(item);

        Console.Read();
    }
}


class LL
{

    private LLNode first;

    public void Add(string s)
    {
        if (this.first == null)
            this.first = new LLNode() { Value = s };
        else
        {
            var node = this.first;
            while (node.Next != null)
                node = node.Next;

            node.Next = new LLNode() { Value = s };
        }
    }


class LLNode
{
    public string Value { get; set; }
    public LLNode Next { get; set; }
}

2 个答案:

答案 0 :(得分:6)

真的不是那么难。要实施IEnumerable,您只需要实施GetEnumerator方法。

为此,您需要创建另一个实现IEnumerator的类。实现IEnumerator非常简单。通常,在创建枚举器时(在GetEnumerator中),您将传递对集合的引用,并且枚举器将跟踪哪个项目是当前项目。然后它会提供MoveNext,只会将Current更改为下一个项目(如果它位于列表末尾则返回false)和Reset只会将Current设置为public class MyLinkedListEnumerator : IEnumerator { private LL myList; private LLNode current; public object Current { get { return current; } } public MyLinkedListEnumerator(LL myList) { this.myList = myList; } public bool MoveNext() { if (current == null) { current = myList.first; } else { current = current.Next; } return current != null; } public void Reset() { current = null; } } 之前第一个节点。

因此,在非常广泛的未经测试的代码术语中,您需要以下内容:

{{1}}

答案 1 :(得分:3)

您需要做的是:

(1)让你的类实现IEnumerable&lt; T&gt;其中T是枚举项的类型。 (在你的情况下,它看起来像是LLNode)。

(2)写一个公共IEnumerator&lt; T&gt; GetEnumerator的。使用“yield”关键字实现它。

(3)添加IEnumerator IEnumerable.GetEnumerator()方法,只返回GetEnumerator()。

以下代码应该明确这一点。在我有&lt; int&gt;的地方,你应该把&lt; LLNode&gt;,假设它是正确的类型。

using System;
using System.Collections;
using System.Collections.Generic;

namespace Demo
{
    internal class Program
    {
        private static void Main()
        {
            var test = new MyDemo();

            foreach (int item in test)
            {
                Console.WriteLine(item);
            }
        }
    }

    public class MyDemo: IEnumerable<int>
    {
        public IEnumerator<int> GetEnumerator()
        {
            // Your implementation of this method will iterate over your nodes
            // and use "yield return" to return each one in turn.

            for (int i = 10; i <= 20; ++i)
            {
                yield return i;
            }
        }

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

我会修改你的代码来正确地完成它,但你发布的代码将无法编译。

[编辑]

现在您已经更新了代码,我可以看到您想要枚举值。这是完成的代码:

using System;
using System.Collections;
using System.Collections.Generic;

namespace Demo
{
    internal class Program
    {
        private LL myList = new LL();

        private static void Main()
        {
            var gogo = new Program();
        }

        public Program()
        {
            myList.Add("test");
            myList.Add("test1");

            foreach (var item in myList) // This now works.
                Console.WriteLine(item);

            Console.Read();
        }
    }


    internal class LL: IEnumerable<string>
    {
        private LLNode first;

        public void Add(string s)
        {
            if (this.first == null)
                this.first = new LLNode
                {
                    Value = s
                };
            else
            {
                var node = this.first;
                while (node.Next != null)
                    node = node.Next;

                node.Next = new LLNode
                {
                    Value = s
                };
            }
        }

        public IEnumerator<string> GetEnumerator()
        {
            for (var node = first; node != null; node = node.Next)
            {
                yield return node.Value;
            }
        }

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

        private class LLNode
        {
            public string Value { get; set; }
            public LLNode Next { get; set; }
        }
    }
}