65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 中的迭代器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2014年3月25日

CPOL

2分钟阅读

viewsIcon

44944

本文简要介绍了 C# 中的迭代器。

引言

本文解释了什么是迭代器以及我们可以通过多少种方式实现迭代器。

背景

迭代器自 C# 的早期版本就可用。但开发者对迭代器的使用较少,也很少实现。在日常工作中,这个概念使用较少,也很少被实现。`yield` 在幕后为计算值生成一个状态机。如果查看编译后的代码,就可以看到这一点。另外需要注意的是,在迭代器中使用的 `Yield` 关键字提供了一种类似于 C# 中 LINQ 的延迟执行。

定义

引用
迭代器是一种方法、get 访问器或运算符,它通过使用 `yield` 关键字对数组或集合类执行自定义迭代 -- 来自 M S D N

在方法中使用迭代器

让我们通过调用 `GetProducts()` 方法来返回产品的简单示例。

public class YieldInMethod
{
    public static IEnumerable<string> GetProducts()
    {
        foreach (var item in Enumerable.Range(1,5))
        {
            yield return "Product" + item.ToString();
        }
    }
    public static void Main(string[] args)
    {
        foreach(var item in GetProducts())
        {
              Console.WriteLine(item);
        }
    }
}

注意:在使用迭代器时,一个重要的点是迭代器的返回类型必须是 `IEnumerable`、`IEnumerator`、`IEnumerable<t>` 或 `IEnumerator<t>`。

发生了什么?

当在迭代器中第一次执行 `yield` return 语句时,它会立即从迭代器返回产品名称,并将“`Product1`”写入控制台。当再次调用迭代器方法时,它会从迭代器方法返回“`Product2`”,并将其写入控制台,依此类推。因此,对于第二次执行,它没有从方法返回“`Product1`”,而是返回了“`Product2`”,因为它知道自己离开的位置并恢复操作,从而返回第二个产品。

在 GET 访问器中使用迭代器

让我们稍微修改上面的代码,以便从 `get` 访问器返回产品和 ID。

public class YieldInGet
{
    public IEnumerable<Products> GetProducts 
    {
        get
        {
            yield return new Products() { Id = 1, Name = "Product1" };
            yield return new Products() { Id = 2, Name = "Product2" };
            yield return new Products() { Id = 3, Name = "Product3" };
        }
        
    }
    public static void Main(string[] args)
    {
        YieldInGet yg = new YieldInGet();
        foreach (Products p in yg.GetProducts)
        {
            Console.WriteLine(String.Format("Product Id: {0}, Name: {1}", p.Id, p.Name));
        }
    }
}
public class Products
{
    public int Id { get; set; }
    public string Name { get; set; }
}

当访问 `GetProducts` 属性时,该属性会一次返回一个产品的列表,其中包含产品的 ID 和名称。

在运算符中使用迭代器

`yield` 在运算符中的实现与 `yield` 在方法中的实现基本相同,只是这个实现使用运算符来返回值。让我们考虑一个简单的斐波那契数列示例,以演示在运算符中使用迭代器。

public class YieldInOperator
{
    public static void Main(string[] args)
    {
        foreach (var item in Fibonacci(5))
        {
            Console.WriteLine(item);       
        }
    }

    public static IEnumerable<int> Fibonacci(int number)
    {
        int a = 0, b = 1;

        yield return a;
        yield return b;

        for (int count = 0; count <= number; count++)
        {
            int temp = a;
            a = b;
            b = temp + b;
            yield return b;
        }
    }
}

当调用 `Fibonnacci(5)` 时,将从 Fibonacci 方法返回“`a`”的值,然后是 `b`,然后是斐波那契数列的数字序列。

摘要

每当需要返回大量值的列表时,可以使用 `yield` 代替返回列表。

© . All rights reserved.