yield(C# 参考)

Posted 时空观察者9号

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了yield(C# 参考)相关的知识,希望对你有一定的参考价值。

yield(C# 参考)

在语句中使用 yield 关键字,表示在该关键字所在的方法、运算符或 get 访问器是迭代器。   通过使用 yield 定义迭代器,可在实现自定义集合类型的 IEnumerableIEnumerator 模式时无需其他显式类(保留枚举状态的类,有关示例,请参阅 IEnumerator<T>)。  

下面的示例演示了 yield 语句的两种形式。

 
复制            
yield return <expression>;
yield break;
备注
 

使用 yield return 语句可一次返回一个元素。

通过 foreach 语句或 LINQ 查询来使用迭代器方法。     foreach 循环的每次迭代都会调用迭代器方法。  迭代器方法运行到 yield return 语句时,会返回一个 expression,并保留当前在代码中的位置。     当下次调用迭代器函数时执行从该位置重新启动。   

可以使用 yield break 语句来终止迭代。

有关迭代器的详细信息,请参阅迭代器(C# 和 Visual Basic)

迭代器的声明必须满足以下要求:

返回 IEnumerableIEnumerator 的迭代器的 yield 类型为 object。如果迭代器返回 IEnumerable<T>IEnumerator<T>,则必须将 yield return 语句中的表达式类型隐式转换为泛型类型参数。

你不能在具有以下特点的方法中包含 yield returnyield break 语句:

不能将 yield return 语句置于 try-catch 块中。  可将 yield return 语句置于 try-finally 语句的 try 块中。  

yield break     语句可以位于 try 块或 catch  块,但不能位于 finally 块。

如果 foreach 主体(在迭代器方法之外)引发异常,则将执行迭代器方法中的 finally 块。

以下代码从迭代器方法返回 IEnumerable<string>,然后遍历其元素。

复制            
IEnumerable<string> elements = MyIteratorMethod();
foreach (string element in elements)
{
   …
}

调用 MyIteratorMethod 并不执行该方法的主体。  相反,该调用会将 IEnumerable<string> 返回到 elements 变量中。  

foreach 循环迭代时,将为 elements 调用 MoveNext 方法。  此调用将执行 MyIteratorMethod 的主体,直至到达下一个 yield return 语句。     yield return 语句返回的表达式不仅决定了循环体使用的 element 变量值,还决定了元素的 Current 属性(它是 IEnumerable<string>)。  

foreach 循环的每个后续迭代中,迭代器主体的执行将从它暂停的位置继续,直至到达 yield return 语句后才会停止。  在到达迭代器方法的结尾或 yield break 语句时,foreach 循环便已完成。  

示例

下面的示例包含一个位于 for 循环内的 yield return 语句。     Process 中的 foreach 语句体的每次迭代都会创建对 Power 迭代器函数的调用。  对迭代器函数的每个调用将继续到 yield return 语句的下一次执行(在 for 循环的下一次迭代期间发生)。  

迭代器方法的返回类型是 IEnumerable(一种迭代器接口类型)。  当调用迭代器方法时,它将返回一个包含数字幂的可枚举对象。  

复制            
public class PowersOf2
{
    static void Main()
    {
        // Display powers of 2 up to the exponent of 8:
        foreach (int i in Power(2, 8))
        {
            Console.Write("{0} ", i);
        }
    }

    public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent)
    {
        int result = 1;

        for (int i = 0; i < exponent; i++)
        {
            result = result * number;
            yield return result;
        }
    }

    // Output: 2 4 8 16 32 64 128 256
}

示例

下面的示例演示一个作为迭代器的 get 访问器。  在该示例中,每个 yield return 语句返回一个用户定义的类的实例。  

复制            
public static class GalaxyClass
{
    public static void ShowGalaxies()
    {
        var theGalaxies = new Galaxies();
        foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
        {
            Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString());
        }
    }

    public class Galaxies
    {

        public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
        {
            get
            {
                yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
                yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
                yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
                yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
            }
        }

    }

    public class Galaxy
    {
        public String Name { get; set; }
        public int MegaLightYears { get; set; }
    }
}

有关更多信息,请参见C# 语言规范。 该语言规范是 C# 语法和用法的权威资料。

以上是关于yield(C# 参考)的主要内容,如果未能解决你的问题,请参考以下文章

[C#]C#中yield return用法分析

[C#]C#中yield return用法分析

c# yield关键字原理详解

使用C# yield关键字来提高性能和可读性

如何在 C# 中使用 yield

C# 中的"yield"使用