在不使用yield return的情况下实现过滤的Iterator

时间:2014-07-24 03:21:00

标签: c# design-patterns oop

我尝试使用过滤器和没有过滤器来显示列表的元素。在这里,我以这种方式使用过滤器来显示可被3整除的元素。我将使用Enumerable和Enumerator接口来实现列表迭代。我正在试图解决这个问题,但我以空手结束,我确信逻辑并无法追踪我犯错误的地方。所以,我只是将我的所有代码放在下面。

在FilterDisplay类中,定义了列表并调用了GetEnumerator()方法,并将其用作

     public class FilterDisplay {
           public void TestIterators(){
          List<int> myList = new List<int> { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5 };
          for (int i = 0; i < myList.Count; i++)
            Console.Write("{0} ", myList[i]);
          Console.WriteLine();

          IEnumerator<int> pi = myList.GetEnumerator();
          while (pi.MoveNext()){
            int x = pi.Current;
            Console.Write("{0} ", x);
          }
          Console.WriteLine();

          MyIntList myIntList = new MyIntList { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5 };
          IEnumerator<int> px = myIntList.GetEnumerator(x => 0 == x % 3);
          while ( px.MoveNext())
            Console.Write("{0} ", px.Current);
          Console.WriteLine();         // displays 3 9 6 3

          Console.ReadKey();
        }
      }
     }

MyIntList类实现了list接口,并且在类中定义并覆盖了GetEnumerator;

public class MyIntList : IList<int>{
    public List<int> MyList = new List<int>();
    public MyIntList() {  }

    public void Add(int item) { MyList.Add(item); }

    public IEnumerator<int> GetEnumerator(){
        return new Enumerator1(MyList);
    }

    public IEnumerator<int> GetEnumerator(Func<int, bool> filter){
        return new Enumerator1(filter, MyList);
    }

在Enumerator1类中,我将定义两个构造函数,用于实现带过滤器的列表和列表。在这里,我尝试覆盖MoveNext()和Current。当我尝试调试项目时,它在Current显示错误。但是,我确定这样定义没有错误。

class Enumerator1 : IEnumerator<int>{
        private int i = -1;
        private MyIntList IntList;

        private Func<int, bool> NewFilter;
        private IEnumerator<int> NewMyList;

        public Enumerator1(IEnumerable<int> list){
            this.NewMyList = list.GetEnumerator();
        }

        public Enumerator1(Func<int, bool> filter, IEnumerable<int> list){
            this.NewFilter = filter;
            this.NewMyList = list.GetEnumerator();
        }

        public bool MoveNext(){
            i++;
            return i < IntList.MyList.Count;
        }

        public int Current { get { return IntList.MyList[i]; } }
        object IEnumerator<int>.Current { get { return NewMyList.Current; } }

        public void Dispose() { }
        public void Reset() { throw new NotSupportedException(); }
    }

除了使用收益率回报之外,我欢迎任何建议,谢谢。

1 个答案:

答案 0 :(得分:0)

我不明白你为什么要这样做(可能是因为“yield return”会在Visual Studio中修复并继续?),但是如果你试图创建一个过滤的枚举器,那么这里是一个:

public class FilteredEnumerator<T> : System.Collections.Generic.IEnumerator<T>
{
    readonly System.Collections.Generic.IEnumerator<T> enumerator;
    readonly System.Func<T, bool> filter; // could be null

    public FilteredEnumerator(System.Collections.Generic.IEnumerable<T> enumerable) : this(enumerable, null) { }

    public FilteredEnumerator(System.Collections.Generic.IEnumerable<T> enumerable, System.Func<T, bool> filter)
    {
        if (enumerable == null)
            throw new System.ArgumentNullException();
        this.enumerator = enumerable.GetEnumerator();
        this.filter = filter; // could be null for unconditional enumeration.
    }

    #region IEnumerator<T> Members

    public T Current { get { return enumerator.Current; } }

    #endregion

    #region IDisposable Members

    public void Dispose()
    {
        enumerator.Dispose();
    }

    #endregion

    #region IEnumerator Members

    object System.Collections.IEnumerator.Current { get { return Current; } }

    public bool MoveNext()
    {
        while (enumerator.MoveNext())
        {
            if (filter == null || filter(enumerator.Current))
                return true;
        }
        return false;
    }

    public void Reset()
    {
        enumerator.Reset();
    }

    #endregion
}