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 }

输出:

 

 

你可能感兴趣的:(foreach)