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

    结果:

  • 相关阅读:
    (转)Windows平台 杀死端口号进程
    android 基础知识总结
    使用安卓手机来运行与调试Android应用程序的步骤
    (转)JavaScript的eval(“{JSON object string}”)问题
    (转)Android手机连接电脑详细图文教程
    Nginx配置中FastCGI的几个命令
    设置nginx的超时时间
    Nginx配置中FastCGI的几个命令
    启用django的gzip压缩支持
    启用django的gzip压缩支持
  • 原文地址:https://www.cnblogs.com/xuekai-to-sharp/p/3555526.html
Copyright © 2020-2023  润新知