C#:foreach语句,yield语句

1. foreach语句

C#编译器会把foreach语句转换为IEnumerable接口的方法和属性。

1 foreach (Person p in persons)
2 {
3 Console.WriteLine(p);
4 }

foreach语句会解析为下面的代码段。

  • 调用GetEnumerator()方法,获得数组的一个枚举
  • 在while循环中,只要MoveNext()返回true,就一直循环下去
  • 用Current属性访问数组中的元素
1 IEnumerator enumerator = persons. GetEnumerator();
2 while (enumerator.MoveNext())
3 {
4 Person p = (Person) enumerator.Current;
5 Console.WriteLine(p);
6 }

2. yield语句

  • yield语句的两种形式:
1 yield return <expression>;
2 yield break;
  • 使用一个yield return语句返回集合的一个元素
  • 包含yield语句的方法或属性是迭代器。迭代器必须满足以下要求

a. 返回类型必须是IEnumerableIEnumerable<T>IEnumeratorIEnumerator<T>

b. 它不能有任何ref或out参数

  • yield return语句不能位于try-catch快。yield return语句可以位于try-finally的try块
 1             try
 2             {
 3                 // ERROR: Cannot yield a value in the boday of a try block with a catch clause
 4                 yield return "test";
 5             }
 6             catch
 7             { }
 8 
 9             try
10             {
11                 // 
12                 yield return "test again";
13             }
14             finally
15             { }
16 
17             try
18             { }
19             finally
20             { 
21                 // ERROR: Cannot yield in the body of a finally clause
22                 yield return ""; 
23             }
  • yield break语句可以位于try块或catch块,但是不能位于finally块

下面的例子是用yield return语句实现一个简单集合的代码,以及用foreach语句迭代集合

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 namespace ConsoleApplication6
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             HelloCollection helloCollection = new HelloCollection();
11             foreach (string s in helloCollection)
12             {
13                 Console.WriteLine(s);
14                 Console.ReadLine();
15             }
16         }
17     }
18 
19     public class HelloCollection
20     {
21         
22         public IEnumerator<String> GetEnumerator()
23         {
24             // yield return语句返回集合的一个元素,并移动到下一个元素上;yield break可以停止迭代
25             yield return "Hello";
26             yield return "World";
27         }
28     }
29 }


使用yield return语句实现以不同方式迭代集合的类:

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 namespace ConsoleApplication8
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             MusicTitles titles = new MusicTitles();
11             foreach (string title in titles)
12             {
13                 Console.WriteLine(title);
14             }
15             Console.WriteLine();
16 
17             foreach (string title in titles.Reverse())
18             {
19                 Console.WriteLine(title);
20             }
21             Console.WriteLine();
22 
23             foreach (string title in titles.Subset(2, 2))
24             {
25                 Console.WriteLine(title);
26                 Console.ReadLine();
27             }
28         }
29     }
30 
31     public class MusicTitles
32     {
33         string[] names = { "a", "b", "c", "d" };
34         public IEnumerator<string> GetEnumerator()
35         {
36             for (int i = 0; i < 4; i++)
37             {
38                 yield return names[i];
39             }
40         }
41 
42         public IEnumerable<string> Reverse()
43         {
44             for (int i = 3; i >= 0; i--)
45             {
46                 yield return names[i];
47             }
48         }
49 
50         public IEnumerable<string> Subset(int index, int length)
51         {
52             for (int i = index; i < index + length; i++)
53             {
54                 yield return names[i];
55             }
56         }
57     }
58 }

输出:

原文地址:https://www.cnblogs.com/LilianChen/p/2949783.html