关于迭代器及yield的用法
1、foreach语句
C#编译器会把foreach语句转换为IEnumerable接口的方法和属性。
1 foreach (Person p in persons) 2 { 3 Console.WriteLine(p); 4 }
foreach语句会解析为下面的代码段。
- 调用GetEnumerator()方法,获得数组的一个枚举
- 在while循环中,只要MoveNext()返回true,就一直循环下去
- 用Current属性访问数组中的元素
IEnumerator enumerator = persons. GetEnumerator(); while (enumerator.MoveNext()) { Person p = (Person) enumerator.Current; Console.WriteLine(p); }
2. yield语句
- yield语句的两种形式:
1 yield return <expression>; 2 yield break;
- 使用一个yield return语句返回集合的一个元素
- 包含yield语句的方法或属性是迭代器。迭代器必须满足以下要求
a. 返回类型必须是IEnumerable、IEnumerable<T>、IEnumerator或 IEnumerator<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块
3、实例
class Program { static void Main(string[] args) { foreach (int i in List.Power(2,10)) { Console.WriteLine(i); } } } public class List { public static IEnumerable<int> Power(int num, int exponent) { int counter = 0; int result = 1; while (counter++ < exponent) { result *= num; yield return result; Thread.Sleep(1000);//效果很有意思 } } }
internal class Program { static void Main(string[] args) { A a=new A(); foreach (string s in a) { Console.WriteLine(s); } Console.WriteLine(); foreach (string s in a.Reverse()) { Console.WriteLine(s); } Console.WriteLine(); foreach (string s in a.GetEnumerator(2,2)) { Console.WriteLine(s); } Console.ReadKey(); } } public class A { private string[] strs = {"a", "b", "c", "d"}; public IEnumerator<string> GetEnumerator() { for (int i = 0; i < 4; i++) { yield return strs[i]; } } public IEnumerable<string> Reverse() { for (int i = 3; i>=0; i--) { yield return strs[i]; } } public IEnumerable<string> GetEnumerator(int index,int length) { for (int i = index; i < index+length ; i++) { yield return strs[i]; } } }
结果:
浮躁的人容易问:我到底该学什么;----别问,学就对了; 浮躁的人容易问:JS有钱途吗;----建议你去抢银行; 浮躁的人容易说:我要中文版!我英文不行!----不行?学呀! 浮躁的人分两种:只观望而不学的人;只学而不坚持的人; 浮躁的人永远不是一个高手。