zoukankan      html  css  js  c++  java
  • C#基础--迭代器初识

    foreach语句是枚举器(enumerator)的消费者,而迭代器(iterator)是枚举器的产生者。

    迭代器模式能提供一种顺序访问一个集合内部的元素,而又不会暴露其内部的方法。当然其缺点就是用foreach语句遍历的同时,不能修改集合内部的元素。

    我们已经在foreach语句中接触过了它 foreach (var item in collection) ,C#利用foreach实现了访问迭代器的内置支持。

    实际上foreach被编译后会产生GetEnumerator和MoveNext方法,还有current属性。

    一.C#2 便捷的语法糖

    下面我们先来介绍C#2.0为实现迭代器提供的便捷语法。

    先看两个单词的翻译 enumerator(枚举器) enumerable(可枚举类型)

    下面举个例子:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    
    namespace ConsoleApp1
    {
        
        class Program
        {
            static IEnumerable<string> AddAB(int Count)
            {
                string str = "h";
                for (int i = 0 ; i < Count; i++)
                {
                    yield return str;
                    str += "a";
                }
                Console.WriteLine("");
                for (int i = 0 ; i < Count; i++)
                {
                    Console.WriteLine("before yoeld return "+str);
                    yield return str;
                    str += "b";
                }
            }
            static void Main(string[] args)
            {
                foreach (var str in AddAB(3))
                {
                    Console.WriteLine(str);
                }
            }
        }
    }

    IEnumerable接口的GetEnumerator方法实现了IEnumerator枚举器类的实例。所以上文的代码是没问题的,后面会给大家示范用IEnumertor接口实现迭代器。

    yield return语句的意思是你向我请求从枚举器产生的下一个元素。

    每次执行到yield return就会返回到他调用者那,但还会执行yield return之后的语句,直到碰到下一条yield return时停止。这个状态一直持续到foreach语句的结束。

    二.C#1 手写迭代器

    再来看看这句话:foreach语句是枚举器(enumerator)的消费者,而迭代器(iterator)是枚举器的产生者。
    【enumerator(枚举器) enumerable(可枚举类型)】

    foreach需要获得一个enumerator,而我们需要用IEnumerator接口实现迭代器。

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace ConsoleApp1
    {
        class Alp : IEnumerable
        {
            string[] value = { "a", "b", "c" };
            public IEnumerator GetEnumerator()
            {
                return new AlpEnumerator(value);
            }
        }
        class AlpEnumerator : IEnumerator
        {
            string[] alp;
            int position = -1;
            public AlpEnumerator(string[] str)
            {
                alp = new string[str.Length];
                for (int i = 0; i < str.Length; i++)
                {
                    alp[i] = str[i];
                }
            }
            public object Current
            {
                get 
                {
                    if (position == -1)
                        throw new InvalidOperationException();
                    if (position >= alp.Length)
                        throw new InvalidOperationException();
                    return alp[position];
                }
            }
    
            public bool MoveNext()
            {
                if (position < alp.Length - 1)
                {
                    position++;
                    return true;
                }
                else 
                    return false;
            }
    
            public void Reset()
            {
                position = -1;
            }
        }
        class Program
        {
            
            static void Main(string[] args)
            {
                Alp alp = new Alp();
                foreach (var item in alp)
                {
                    Console.WriteLine(item);
                }
            }
        }
    }
    • Current      获取当前位置
    • MoveNext  判断是否可移动到下一位
    • Reset         将位置重置为初始位置
  • 相关阅读:
    【计算机组成】运算器与运算方法
    【计算机组成】数据表示
    【计算机组成】概论
    【Python】基础总结
    Robot Framework(14)- Variables 表的详细使用和具体例子
    Robot Framework(13)- RF 循环的详细使用
    Robot Framework(12)- 详细解读 RF 的变量和常量
    Robot Framework(11)- 用户关键字的详解
    Robot Framework(10)- 使用资源文件
    Robot Framework(9)- 使用变量文件
  • 原文地址:https://www.cnblogs.com/AD-milk/p/12459944.html
Copyright © 2011-2022 走看看