C# 迭代器

本文深入探讨C#中的迭代器概念,包括IEnumerator接口的实现,yield关键字的使用,以及如何利用IEnumerable接口简化循环访问。通过具体代码示例,解析自定义集合的迭代逻辑。
IEnumerator

实现 IEnumerator 接口的类才是真正的迭代器,它定义了各项元素被循环访问的逻辑。

// 实现 IEnumerator
public class WeekEnumerator : IEnumerator
{
    string[] week = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
    int position = -1;

    public object Current => week[position];

    public bool MoveNext()
    {
        position++;
        return position < week.Length;
    }

    public void Reset()
    {
        position = -1;
    }
}

// 循环迭代器
var week = new WeekEnumerator ();
while (week .MoveNext())
{
	Debug.Log(week.Current);
}
yield return

yield 是一种语法糖,会自动实现 IEnumerator 接口的 Current、MoveNext 等方法。即完成 MonthEnumerator 所做的事。所以,语句中使用了 yield 关键字的方法、运算符或 get 访问器也是迭代器。

使用多个 yield 语句,可以代替手动实现 IEnumerator 的繁琐操作。

// 定义迭代器方法
IEnumerator GetWeek()
{
	// 多个 yield 语句合起来生成了一个实现 IEnumerator 接口的类(相当于 WeekEnumerator )
	// yield return 的返回类型是 IEnumerator
	yield return "Mon";
	yield return "Tue";
	yield return "Wed";
	yield return "Thu";
	yield return "Fri";
	yield return "Sat";
	yield return "Sun";
}

// 循环这个迭代器方法
var week = GetWeek();
while (week.MoveNext())
{
	Debug.Log(week.Current);
}
IEnumerable

IEnumerable 接口实际上就是简化了循环访问,包装了 IEnumerator 以便通过 foreach 进行循环

// IEnumerable 接口只有一个获取 IEnumerator 的方法
public interface IEnumerable
{
	IEnumerator GetEnumerator();
}

// 使用 foreach 循环 List,它是实现了 IEnumerable 接口的类型
var array = new List<int> { 100, 101, 102 };
foreach (var item in array)
{
	Debug.Log(item);
}

// 这是编译器内部转换的 foreach 代码
var enumerator = array.GetEnumerator();
while (enumerator.MoveNext())
{
	Debug.Log(enumerator.Current);
}

即,IEnumerator 类在使用 IEnumerable 接口包装后,可使用 foreach 循环,否则需使用 MoveNext 手动完成。C# 中自带集合,一般都实现自 IEnumerable 接口,方便可用 foreach 进行迭代。

使用 IEnumerable 与 IEnumerator 自定义集合
// 实现 IEnumerable 接口
public class Week : IEnumerable
{
	// 只为取得 IEnumerator
    public IEnumerator GetEnumerator()
    {
        return new WeekEnumerator();
    }
}

// 实现 IEnumerator 接口
public class WeekEnumerator : IEnumerator
{
	// 和第一个示例中一样
    ...
}

由于 yield 帮助生成 IEnumerator 类型,所以可以使用 yield 来简化自定义集合的定义

// 只需要实现 IEnumerable 接口,通过 yield 语法糖生成 IEnumerator
public class Week : IEnumerable
{
    string[] days = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

    public IEnumerator GetEnumerator()
    {
        for (int i = 0; i < days.Length; i++)
        {
            yield return days[i];
        }
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值