关于迭代器及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];

            }

        }

    }

结果:

 

你可能感兴趣的:(yield)