C#:foreach语句,yield语句

简介: 原文:C#:foreach语句,yield语句1. foreach语句 C#编译器会把foreach语句转换为IEnumerable接口的方法和属性。 1 foreach (Person p in persons) 2 { 3 Console.WriteLine(p); 4 } foreach语句会解析为下面的代码段。
原文: 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 }

输出:

 

 

目录
相关文章
|
7月前
|
C#
C#学习相关系列之yield和return的区别
C#学习相关系列之yield和return的区别
126 1
|
7月前
|
编译器 数据处理 C#
C#中的异步流:使用IAsyncEnumerable<T>和await foreach实现异步数据迭代
【1月更文挑战第10天】本文介绍了C#中异步流的概念,并通过使用IAsyncEnumerable<T>接口和await foreach语句,详细阐述了如何异步地迭代数据流。异步流为处理大量数据或需要流式处理数据的场景提供了一种高效且非阻塞性的方法,使得开发者能够更优雅地处理并发和数据流问题。
|
7月前
|
SQL 开发框架 .NET
EntityFramework数据持久化复习资料3、C#拓展方法与yield关键字使用
EntityFramework数据持久化复习资料3、C#拓展方法与yield关键字使用
58 0
|
1月前
|
安全 编译器 程序员
C# 中 foreach 循环和 for 循环深度比较
为什么建议你多数情况下使用 foreach 进行遍历循环?看完你就明白了
C#中For循环和Foreach循环的区别
C#中For循环和Foreach循环的区别
136 0
|
7月前
|
C# 图形学
【Unity 3D】C#中while do while for foreach等循环语句的讲解(附测试代码)
【Unity 3D】C#中while do while for foreach等循环语句的讲解(附测试代码)
254 0
C# for和foreach两种循环的效率问题
C# for和foreach两种循环的效率问题
|
算法 C#
【愚公系列】2021年11月 C#版 数据结构与算法解析 for和foreach性能分析
【愚公系列】2021年11月 C#版 数据结构与算法解析 for和foreach性能分析
163 0
【愚公系列】2021年11月 C#版 数据结构与算法解析 for和foreach性能分析
|
C# 索引
C#中的yield
C#中的yield
112 0
|
存储 程序员 编译器
小解c# foreach原理
小解c# foreach原理
182 0