1、foreach语句
C#编译器会把foreach语句转换为IEnumerable接口的方法和属性。
1 foreach (Person p in persons) 2 { 3 Console.WriteLine(p); 4 }
foreach语句会解析为下面的代码段。
IEnumerator enumerator = persons. GetEnumerator(); while (enumerator.MoveNext()) { Person p = (Person) enumerator.Current; Console.WriteLine(p); }
2. yield语句
1 yield return <expression>; 2 yield break;
a. 返回类型必须是IEnumerable、IEnumerable<T>、IEnumerator或 IEnumerator<T>。
b. 它不能有任何ref或out参数
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 }
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]; } } }
结果: