关于迭代器及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. 返回类型必须是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块

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];
            }
        }
    }

结果:

 

posted @ 2014-02-19 11:11  蚂蚁拉车  阅读(335)  评论(0编辑  收藏  举报