
C# 迭代器模式讲解和代码示例
迭代器是一种行为设计模式, 让你能在不暴露复杂数据结构内部细节的情况下遍历其中所有的元素。
在迭代器的帮助下, 客户端可以用一个迭代器接口以相似的方式遍历不同集合中的元素。
复杂度:
流行度:
使用示例: 该模式在 C# 代码中很常见。 许多框架和程序库都使用它来提供遍历其集合的标准方式。
识别方法: 迭代器可以通过导航方法 (例如 next
和 previous
等) 来轻松识别。 使用迭代器的客户端代码可能没有其所遍历的集合的直接访问权限。
概念示例
本例说明了迭代器设计模式的结构并重点回答了下面的问题:
- 它由哪些类组成?
- 这些类扮演了哪些角色?
- 模式中的各个元素会以何种方式相互关联?
Program.cs: 概念示例
using System;
using System.Collections;
using System.Collections.Generic;
namespace RefactoringGuru.DesignPatterns.Iterator.Conceptual
{
abstract class Iterator : IEnumerator
{
object IEnumerator.Current => Current();
// Returns the key of the current element
public abstract int Key();
// Returns the current element
public abstract object Current();
// Move forward to next element
public abstract bool MoveNext();
// Rewinds the Iterator to the first element
public abstract void Reset();
}
abstract class IteratorAggregate : IEnumerable
{
// Returns an Iterator or another IteratorAggregate for the implementing
// object.
public abstract IEnumerator GetEnumerator();
}
// Concrete Iterators implement various traversal algorithms. These classes
// store the current traversal position at all times.
class AlphabeticalOrderIterator : Iterator
{
private WordsCollection _collection;
// Stores the current traversal position. An iterator may have a lot of
// other fields for storing iteration state, especially when it is
// supposed to work with a particular kind of collection.
private int _position = -1;
private bool _reverse = false;
public AlphabeticalOrderIterator(WordsCollection collection, bool reverse = false)
{
this._collection = collection;
this._reverse = reverse;
if (reverse)
{
this._position = collection.getItems().Count;
}
}
public override object Current()
{
return this._collection.getItems()[_position];
}
public override int Key()
{
return this._position;
}
public override bool MoveNext()
{
int updatedPosition = this._position + (this._reverse ? -1 : 1);
if (updatedPosition >= 0 && updatedPosition < this._collection.getItems().Count)
{
this._position = updatedPosition;
return true;
}
else
{
return false;
}
}
public override void Reset()
{
this._position = this._reverse ? this._collection.getItems().Count - 1 : 0;
}
}
// Concrete Collections provide one or several methods for retrieving fresh
// iterator instances, compatible with the collection class.
class WordsCollection : IteratorAggregate
{
List<string> _collection = new List<string>();
bool _direction = false;
public void ReverseDirection()
{
_direction = !_direction;
}
public List<string> getItems()
{
return _collection;
}
public void AddItem(string item)
{
this._collection.Add(item);
}
public override IEnumerator GetEnumerator()
{
return new AlphabeticalOrderIterator(this, _direction);
}
}
class Program
{
static void Main(string[] args)
{
// The client code may or may not know about the Concrete Iterator
// or Collection classes, depending on the level of indirection you
// want to keep in your program.
var collection = new WordsCollection();
collection.AddItem("First");
collection.AddItem("Second");
collection.AddItem("Third");
Console.WriteLine("Straight traversal:");
foreach (var element in collection)
{
Console.WriteLine(element);
}
Console.WriteLine("\nReverse traversal:");
collection.ReverseDirection();
foreach (var element in collection)
{
Console.WriteLine(element);
}
}
}
}
Output.txt: 执行结果
Straight traversal:
First
Second
Third
Reverse traversal:
Third
Second
First