关于C#迭代器

时间:2023-03-10 04:26:04
关于C#迭代器

>1 IEnumerator与IEnumerable

IEnumerator与IEnumerable两个接口是用于实现迭代器的接品只要实现了IEnumerable就可以用foreach,linq等语法,一般来说实现 IEnumerable接口的是Collection的数据,也就是一个集合,比如List,ArrayList等这种类型,因为一般foreach,linq都是在一个集合中查询

而IEnumerator主要是支持IEnumerator一个接口,里面提供了用于迭代的属 性和方法,两个接口代码

public interface IEnumerable{
IEnumerator GetEnumerator();
} public interface IEnumerable{
object Current{get;}
bool MoveNext();
void Reset();
}

下面是简单实现自己类支持迭代

public class Man
{
public string Name { get; set; }
public int Age { get; set; } public override string ToString()
{
return string.Format("{0} {1}", Name, Age);
}
} public class ManEnum : IEnumerator
{ private Man[] man;
private int index = -; public ManEnum(Man[] man)
{
this.man = man;
} public object Current
{
get { return man[index]; }
} public bool MoveNext()
{
index++;
return index < man.Length;
} public void Reset()
{
index = -;
}
} public class ManCollection : IEnumerable
{
private ManEnum me; public ManCollection(Man[] man)
{
this.me = new ManEnum(man);
} public IEnumerator GetEnumerator()
{
return me;
}
}

下面测试可以用foreach打印信息出来

            Man[] man = { new Man() { Name = "小明", Age =  }, 

new Man() { Name = "小红", Age =  } };
ManCollection mc = new ManCollection(man); foreach (var m in mc) {
Console.WriteLine(m);
}

>2 yield我们可以用yield更方便快捷的写出迭代器,可以实现返回IEnumerable或 IEnumerator的对象

下面是用yield修改的代码,我们可以直接去掉ManEnum类.把ManCollection 改一下

    public class ManCollection : IEnumerable
{
private Man[] mans; public ManCollection(Man[] man)
{
this.mans = man;
} public IEnumerator GetEnumerator()
{
for (int i = ; i < mans.Length; i++)
{
yield return mans[i];
}
}
}

这次我们用linq来查询出年龄大于等于18岁的.

            Man[] man = { new Man() { Name = "小明", Age =  }, 

new Man() { Name = "小红", Age =  } };
ManCollection mc = new ManCollection(man); var q = from r in man
where r.Age >=
select r;
foreach (var x in q) {
Console.WriteLine(x);
}

可以看出没有问题,yield还有一种就是yield break;可以在迭代过程中打段
,类似于循环中break一样的效果.