繁体   English   中英

实现IEnumerable <T> 在C#上从头开始构建的链表

[英]Implement IEnumerable<T> in C# on linked list built from scratch

我已经从头开始在C#中构建了一个链表,并且具有可靠的单元测试覆盖率以确保它正常工作。

为了方便地比较链接列表和许多值,我使用标准手动“枚举”值,而CurrentNode.Next!= null,提前技术并将这些值存储在C#列表或数组中。

我想在我的自定义LinkedList类上实现IEnumerable,而不是依赖于从私有后备集合中获取枚举器。

这是我的LinkedList类的代码。 我觉得我忽略了一些简单的东西,因为枚举器应该只是你从集合类中获得的对象,它提供了一个起点和下一个方法,据我所知。 我只是不能让它以通用的方式工作。

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

namespace CSharpLibrary.DataStructures.LinkedLists
{
    public class LinkedList<T> : IEnumerable<T>
    {
        public Node<T> First { get; private set; }
        public Node<T> Current { get; set; }

        public LinkedList(T initialValue)
        {
            First = new Node<T>(initialValue);
        }

        public void AddNodeToEnd(T value)
        {
            Node<T> last = GetLastNode();
            last.Next = new Node<T>(value);
        }

        public Node<T> GetLastNode()
        {
            Node<T> last = First;
            Node<T> current = First;
            while (current.Next != null)
            {
                last = current.Next;
                current = current.Next;
            }
            return current;
        }


        public void Reset()
        {
            Current = First;
        }

        public IEnumerator<T> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }
}

要添加到Bradley的答案,请注意返回IEnumerator<T>也支持yield关键字:

public class LinkedList<T> : IEnumerable<T>
{
    ...

    // this will automagically create the 
    // appropriate class for you
    public IEnumerator<T> GetEnumerator()
    {
        Node<T> current = First;
        while (current != null)
        {
            yield return current.Value;
            current = current.Next;
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        // this will invoke the public generic
        // version, so there is no recursion
        return this.GetEnumerator();
    }
}

但是,您应该从父类中删除CurrentReset() ,它们不属于那里。 并且您的GetLastNode()方法有两个重复的变量,您可以删除其中一个。

由于您已创建自定义集合,因此您将无法仅使用现有的IEnumerator实现。 你需要创建一个:

public class LinkedListEnumerator<T> : IEnumerator<T>
{
   public LinkedListEnumerator(LinkedList<T> collection)
   {
   }
   ...
}

我将要枚举的集合传递给构造函数。 其他方式可行,但这似乎是最简单的方法。 现在你的IEnumerable<T>实现是:

    public IEnumerator<T> GetEnumerator()
    {
        return new LinkedListEnumerator<T>(this);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return new LinkedListEnumerator<T>(this);
    }

实际的IEnumerator实现作为练习留下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM