在C#中实现一个自定义的迭代器,并说明在何种情况下会使用迭代器

在C#中实现一个自定义的迭代器,并说明在何种情况下会使用迭代器

编码文章call10242025-02-11 11:31:3213A+A-

C# 中自定义迭代器的实现

自定义迭代器的概念

  • 在 C# 中,迭代器允许我们以逐个枚举的方式遍历集合。
  • 通过使用 yield return 和 yield break 关键字,可以轻松地定义自定义迭代器。

代码示例:自定义迭代器实现一个斐波那契数列生成器

using System;
using System.Collections;

class FibonacciSequence : IEnumerable
{
    private readonly int _count;

    public FibonacciSequence(int count)
    {
        _count = count;
    }

    // 自定义迭代器
    public IEnumerator GetEnumerator()
    {
        int prev = 0, current = 1;

        for (int i = 0; i < _count; i++)
        {
            yield return prev; // 返回当前值
            int next = prev + current; // 计算下一个数
            prev = current; // 更新前一个值
            current = next; // 更新当前值
        }
    }
}

class Program
{
    static void Main()
    {
        Console.WriteLine("斐波那契数列(前 10 项):");

        // 创建斐波那契序列生成器
        FibonacciSequence fibonacci = new FibonacciSequence(10);

        // 使用 foreach 遍历
        foreach (var number in fibonacci)
        {
            Console.Write(number + " ");
        }
    }
}

运行结果

斐波那契数列(前 10 项):
0 1 1 2 3 5 8 13 21 34

关键点解析

1.yield return和yield break

  • yield return:每次调用迭代器时,会将当前值返回给调用方,同时保持迭代器的状态。在下一次迭代时,会从上一次暂停的位置继续执行。
  • yield break:立即退出迭代,停止后续的枚举。

2. 实现IEnumerable接口

  • 自定义集合类需要实现 IEnumerable 接口并提供 GetEnumerator 方法。
  • GetEnumerator 方法定义了具体的迭代逻辑。

3. 可枚举对象与foreach

  • 使用 foreach 时,迭代器会自动被调用,简化了集合遍历的代码。

使用自定义迭代器的场景

  1. 延迟计算(Lazy Evaluation)
  2. 生成大数据集合时,按需计算数据而不是一次性加载整个集合。
  3. 如:斐波那契数列、素数序列生成等。
  4. 自定义遍历逻辑
  5. 当集合需要特殊的遍历逻辑,而不是线性顺序时。
  6. 如:树形结构的深度优先或广度优先遍历。
  7. 抽象复杂的数据生成过程
  8. 将复杂的数据生成逻辑封装在迭代器中,隐藏内部实现细节。

扩展示例:带条件的自定义迭代器

以下示例生成仅包含偶数的斐波那契数列:

public IEnumerator GetEvenFibonacciNumbers()
{
    int prev = 0, current = 1;

    for (int i = 0; i < _count; i++)
    {
        if (prev % 2 == 0)
        {
            yield return prev; // 返回偶数值
        }

        int next = prev + current;
        prev = current;
        current = next;
    }
}

使用方式:

foreach (var number in fibonacci.GetEvenFibonacciNumbers())
{
    Console.Write(number + " ");
}

结果:

0 2 8 34

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4