FilterEnumerator——对数据集进行过滤迭代

此迭代器是ConvertEnumerator的姊妹类。设计出发点是为了在获取数据集的子集时避免创建数据集对象。

此类适用以满足以下条件的场景:

1、存在一个数据集A。

2、在程序中需要获取一个A的子集,且不止一处需要。因此,过滤的逻辑需要包装。

3、A变化频繁或获取子集的操作不频繁。

由于需要包装,一般情况下,只能创建一个新数据集来保存A的子集再向外提供。

FilterEnumerator能够映射到一个原始数据集,允许用户对其进行迭代访问并且访问到的元素均是原数据集中满足指定条件的元素。条件比较逻辑由使用方通过委托传递给FilterEnumerator。

原码(泛型版本):

public class FilterEnumerator<T>:IEnumerator<T>,IDisposable,IEnumerator
{
    #region Fields

    private IEnumerator<T> Source;

    private Predicate<T> Filter;

    #endregion

    #region Properties

    /// <summary>
    /// 当前值
    /// </summary>
    public T Current
    {
        get { return Source.Current; }
    }

    /// <summary>
    /// 当前值
    /// </summary>
    object IEnumerator.Current
    {
        get { return Source.Current; }
    }

    #endregion

    #region Methods

    public FilterEnumerator(IEnumerable<T> source, Predicate<T> filter)
    {
        if (object.ReferenceEquals(null, source) || object.ReferenceEquals(null, filter))
        {
            throw new ArgumentNullException();
        }

        this.Source = source.GetEnumerator();
        this.Filter = filter;
    }

    public FilterEnumerator(IEnumerator<T> source, Predicate<T> filter)
    {
        if (object.ReferenceEquals(null, source) || object.ReferenceEquals(null, filter))
        {
            throw new ArgumentNullException();
        }

        this.Source = source;
        this.Filter = filter;
    }

    public bool MoveNext()
    {
        while (Source.MoveNext())
        {
            if (Filter(Source.Current)) return true;
        }
        return false;
    }

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

    /// <summary>
    /// 释放资源
    /// </summary>
    public void Dispose()
    {

    }

    #endregion
}

public class FilterEnumeratorProvider<T>:IEnumerable<T>,IDisposable,IEnumerable
{
    #region Fields

    private IEnumerable<T> Source;

    private Predicate<T> Filter;

    #endregion

    #region Methods

    public FilterEnumeratorProvider(IEnumerable<T> source, Predicate<T> filter)
    {
        if (object.ReferenceEquals(null, source) || object.ReferenceEquals(null, filter))
        {
            throw new ArgumentNullException();
        }

        this.Source = source;
        this.Filter = filter;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return new FilterEnumerator<T>(Source, Filter);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return new FilterEnumerator<T>(Source, Filter); 
    }

    public void Dispose()
    {
        
    }

    #endregion
}
原文地址:https://www.cnblogs.com/yedaoq/p/1738715.html