迭代器模式是一种行为设计模式,它提供了一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表现。这种模式在C#和.NET框架中非常常见,通过实现IEnumerator和IEnumerable接口来支持迭代器的实现。当需要实现自己的聚合对象时,应该实现这些接口以提供一种遍历聚合对象的方式。
在以下情况下,应该使用迭代器模式:
在C#中实现迭代器模式的UML图可以包括以下元素:
聚合项(AggregateItem):一个简单的数据结构。
聚合接口(Aggregate):包含GetIterator方法,用于返回迭代器。
迭代器接口(Iterator):定义了迭代器的行为。
聚合实现(AggregateImpl)和迭代器实现(IteratorImpl):实现了聚合和迭代器接口的具体类。
IEnumerator和IEnumerable是C#中实现迭代器模式的方式。IEnumerable接口暴露了枚举器,它支持对非泛型或泛型集合的简单迭代。IEnumerable广泛用于LINQ,并且是暴露LINQ功能的基础。IEnumerator接口支持对非泛型或泛型集合的简单迭代。枚举器是一种只读方式遍历集合。
以下是使用IEnumerator和IEnumerable接口实现迭代器模式的示例代码:
#region Aggregate Item
class AggregateItem
{
// Properties
public string Data { get; set; }
// Constructor
public AggregateItem(string data)
{
Data = data;
}
}
#endregion
#region Aggregate Object
interface Aggregate
{
Iterator GetIterator();
}
class AggregateImpl : Aggregate
{
private readonly List _aggregate;
public int Count
{
get { return _aggregate.Count; }
}
public AggregateItem this[int index]
{
get { return _aggregate[index]; }
set { _aggregate[index] = value; }
}
public AggregateImpl()
{
_aggregate = new List();
}
public Iterator GetIterator()
{
return new IteratorImpl(this);
}
}
#endregion
#region Iterator
interface Iterator
{
object First();
object Next();
bool IsDone();
object Current();
}
class IteratorImpl : Iterator
{
private readonly AggregateImpl _aggregate;
private int _nCurrentIndex;
public object First()
{
return _aggregate[0];
}
public object Next()
{
object result = null;
if (_nCurrentIndex < _aggregate.Count - 1)
{
result = _aggregate[_nCurrentIndex];
_nCurrentIndex++;
}
return result;
}
public bool IsDone()
{
return _nCurrentIndex >= _aggregate.Count;
}
public object Current()
{
return _aggregate[_nCurrentIndex];
}
public IteratorImpl(AggregateImpl aggregate)
{
_nCurrentIndex = 0;
_aggregate = aggregate;
}
}
#endregion
var strList = new List { "str1", "str2", "str3" };
IEnumerator<string> enumerator = strList.GetEnumerator();
string str;
while (enumerator.MoveNext())
{
str = enumerator.Current;
if (!string.IsNullOrEmpty(str))
{
Console.WriteLine("{0}", str);
}
}