技术开发 频道

.Net编程接口剖析系列之迭代器


设计一个集合类

    通常,IEnumerator和IEnumerable是一起使用的。假设我们设计一个属于自己的一个数据结构类MyCollection,并且让他可以被枚举,那么整体上应该怎么设计呢?我们看看下面的代码。
class MyCollection:IEnumerable 
{
public struct MyEmurator : IEnumerator
{
//此处省略实现代码
}
//此处省略部分实现代码
public IEnumerator GetEnumerator()
{
return new MyEmurator(this);
}
}
   这是一个典型的对IEnumerator和IEnumerable的应用方式。几乎所有的System.Collection里面的容器都是都是这样来设计的。将容器类型本身实现IEnumerable,表明容器是可枚举的。而迭代器类型则是一个嵌套类型,通过容器类的接口函数GetEnumerator来返回迭代器的实例。通常一个容器和它的迭代器是紧密相关的,并且一个容器配备一个迭代器已经足以,那么将迭代器定义为嵌套类型,避免了管理的混乱。

实现一个2D List类型

    我们这里说的二维List类型,其实就是实现一个以List为元素的List,简而言之,这个List2D就是用来存放List的一个List;但是我们枚举的时候,并不想要枚举List2D里面的list, 而是想直接枚举list里面的元素。
    我们这里定义了一个泛型类List2D<T> ,实现了IEnumerable<T>接口。这里为了精简代码,这里没有让List2D实现IList接口,只提供了Add、Clear等几个简单方法。不多说了,还是来看看下面的代码吧!
class List2D<T> : IEnumerable<T> 
{
//内嵌迭代器类型
public struct Emurator : IEnumerator<T>
{
//此处代码先不写出
}
private List<List<T>> _lists=new List<List<T>>();//存储列表

public List<T> this[int index]
{
get { return _lists[index]; }
}

public int Count
{
get
{
int count = 0;
foreach (List<T> list in _lists)
{
count += list.Count;
}
return count;
}
}

public void Add(List<T> item)
{
_lists.Add(item);
}

public void Clear()
{
_lists.Clear();
}

#region IEnumerable Members

public IEnumerator GetEnumerator()
{
return ((IEnumerable<T>)this).GetEnumerator();
}
#endregion

#region IEnumerable<T> Members

IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return new Emurator(this);
}
#endregion
}
0
相关文章