public object Current
{
get
{
if(position==-1||position==set.values.Length)
{
throw new InvalidOperationException();
}
int index = position;
return set.values[index];
}
}
public bool MoveNext()
{
if(position!=set.values.Length)
{
position++;
}
return position < set.values.Length;
}
public void Reset()
{
position = -1;
}
}
测试程序:
object[] values = { "a", "b", "c", "d", "e" };
MySet mySet = new MySet(values);
foreach (var item in mySet)
{
Console.WriteLine(item);
}
这个例子也证明了foreach内部使用迭代器的MoveNext和Current完成遍历。
上面的例子中手写实现迭代器是十分麻烦的,在c#1.0中这是唯一的方式。在c#2.0中,我们可以使用yield语法糖简化迭代器。
public IEnumerator GetEnumerator()
{
for (int i = 0; i < values.Length; i++)
{
yield return values[i];
}
}
IEnumerable和IEnumerator虽然实现简单,只有简单的几个成员,但是却支撑起了C#语言中集合这座高楼大厦。
ICollection和ICollection从第一张图中,我们可以得知ICollection继承于IEnumerable接口,并且扩展了IEnumerable接口。
主要扩展的功能有:
新增了属性Count,用于记录集合元素个数
支持添加元素和移除元素
支持是否包含某元素
支持清空集合等等
对于任何实现了ICollection接口的集合,我们都可以通过第1条Count属性获取当前集合的元素数,所以这些集合也被称为计数集合。
IList 和IListIList接口直接继承于ICollection接口和IEnumerable接口,并且扩展了通过索引操作集合的功能。
主要扩展的功能有:
通过索引获取集合中某个元素
通过元素获取元素在集合中的索引值
通过索引插入元素到集合指定位置
移除集合指定索引处的元素
IDictionary<TKEY, tvalue="">和IDictionaryIDictionary接口直接继承于ICollection接口和IEnumerable接口,存储的元素是键值对,扩展了通过键操作键值对集合的功能。
主要扩展的功能有:
通过键KEY获取值VALUE
插入新的键值对{KEY:VALUE}
是否包含KEY
通过KEY移除键值对元素
主要的集合的接口介绍完了,下面我们来看一下具体的集合类型。
关联性泛型集合类 1.Dictionary<TKEY,TVALUE>Dictionary<TKEY,TVALUE>的查询数据所花费的时间是所有集合类里面最快的,因为其内部使用了散列函数加双数组来实现,所以其查询数据操作的时间复杂度可以认为是O(1)。Dictionary<TKEY,TVALUE>的实现是一种典型的牺牲空间换取时间(双数组)的做法。
Dictionary<TKEY,TVALUE>添加新元素的实现:
Dictionary<TKEY,TVALUE>内部有两个数组,一个数组名为buckets,用于存放由多个同义词组成的静态链表头指针(链表的第一个元素在数组中的索引号,当它的值为-1时表示此哈希地址不存在元素);另一个数组为entries,它用于存放哈希表中的实际数据,同时这些数据通过next指针构成多个单链表。entries数组中所存放的是Entry结构体,Entry结构体由4个部分组成,如下所示: