田敏
返回博客列表
技术

迭代器模式

田敏
2024-11-272 分钟阅读
Design PatternSoftware Engineering

迭代器模式

迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式。

迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

迭代器模式属于行为型模式。

介绍

意图

允许顺序访问一个聚合对象中的元素,同时不暴露对象的内部表示。

主要解决的问题

  • 提供一种统一的方法来遍历不同的聚合对象。

使用场景

  • 当需要遍历一个聚合对象,而又不希望暴露其内部结构时。

实现方式

  • 定义迭代器接口:包含hasNext()next()等方法,用于遍历元素。
  • 创建具体迭代器:实现迭代器接口,定义如何遍历特定的聚合对象。
  • 聚合类:定义一个接口用于返回一个迭代器对象。

关键代码

  • 迭代器接口:规定了遍历元素的方法。
  • 具体迭代器:实现了迭代器接口,包含遍历逻辑。

应用实例

  • List集合容器的实现

在 C# 中,可以通过实现 IEnumerableIEnumerator 接口来自定义迭代器。以下是一个手动实现迭代器的示例:


需求场景

假设我们要创建一个可以反向迭代的集合类 ReverseCollection


代码实现

1. 自定义集合类 ReverseCollection

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

public class ReverseCollection<T> : IEnumerable<T>
{
    private readonly T[] _items;

    public ReverseCollection(T[] items)
    {
        _items = items ?? throw new ArgumentNullException(nameof(items));
    }

    // 实现 GetEnumerator 方法,返回自定义的枚举器
    public IEnumerator<T> GetEnumerator()
    {
        return new ReverseEnumerator(_items);
    }

    // 显式实现非泛型版本的 GetEnumerator
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    // 自定义的枚举器
    private class ReverseEnumerator : IEnumerator<T>
    {
        private readonly T[] _items;
        private int _position;

        public ReverseEnumerator(T[] items)
        {
            _items = items;
            _position = _items.Length; // 从数组尾部开始
        }

        // 返回当前元素
        public T Current
        {
            get
            {
                if (_position < 0 || _position >= _items.Length)
                    throw new InvalidOperationException("Enumerator is out of bounds.");
                return _items[_position];
            }
        }

        // 显式实现非泛型版本的 Current
        object IEnumerator.Current => Current;

        // 移动到下一个元素
        public bool MoveNext()
        {
            _position--;
            return _position >= 0;
        }

        // 重置枚举器
        public void Reset()
        {
            _position = _items.Length;
        }

        // 释放资源
        public void Dispose()
        {
            // 这里通常用于释放非托管资源
        }
    }
}

使用示例

public static void Main()
{
    var items = new[] { 1, 2, 3, 4, 5 };
    var reverseCollection = new ReverseCollection<int>(items);

    Console.WriteLine("Iterating in reverse order:");
    foreach (var item in reverseCollection)
    {
        Console.WriteLine(item);
    }
}

运行结果

Iterating in reverse order:
5
4
3
2
1

代码解析

  1. IEnumerableIEnumerator
    • IEnumerable<T> 是集合类支持 foreach 迭代的标准接口。
    • IEnumerator<T> 是枚举器接口,用于定义元素的迭代方式。
  2. 自定义迭代逻辑
    • ReverseEnumerator 中,迭代从集合尾部开始(即索引从 Length - 10)。
  3. 资源管理
    • Dispose 方法一般用于释放非托管资源;这里的实现只是一个占位符。
  4. Reset 方法
    • Reset 是为了重置迭代器的状态,以便可以从头开始迭代。

总结

通过手动实现 IEnumerableIEnumerator 接口,可以灵活定义任何迭代逻辑,例如反向迭代、按条件迭代等。这种方式非常适合需要自定义复杂集合遍历逻辑的场景。

版权协议:MIT返回列表