• C# 枚举器和迭代器


    foreach语句

    我们可以用foreach语句来遍历数组中的每一个元素。

    为什么数组可以这么做,是因为数组提供了叫做 枚举器的对象

    获取一个对象的枚举器方法是 调用对象的GetEnumerator方法,那么如果实现了这个方法的类型叫做 可枚举类型

     IEnumerator接口

    实现IEnumerator接口的枚举器有三个函数成员

    Current是返回序列中当前位置项的属性

    MoveNext把枚举器前进到下一项的方法

    • 新的位置有效 返回true
    • 新的位置无效 返回false
    • 起始的位置在第一项之前,所有得在第一次使用Current之前调用

    Reset是把位置重置为原始状态的方法

    所以知道了枚举器,就可以模仿foreach循环遍历集合中的项

    IEnumerable接口

    可吗,枚举类是实现了IEnumerable接口的类,IEnumerable接口只有一个成员:GetEnumerator方法,它返回对象的枚举器

    代码演示如下:

    使用IEnumerator和IEnumerable

    代码中展示了一个可枚举类:Spectrum,枚举器类为Color_Enumerator

    using System;
    using System.Collections;
    using System.Linq;
    
    namespace ConsoleApp3
    {
        class ColorEnumerator : IEnumerator
        {
            private string[] _colors;
            private int _position = -1;
    
            public ColorEnumerator(string[] theColors)
            {
                _colors = new string[theColors.Length];
                for (int i = 0; i < theColors.Length; i++)
                {
                    _colors[i] = theColors[i];
                }
            }
    
            public object Current
            {
                get
                {
                    if(_position == -1)
                    {
                        throw new InvalidOperationException();
                    }
    
                    if (_position >= _colors.Length)
                    {
                        throw new InvalidOperationException();
                    }
    
                    return _colors[_position];
                }
            }
    
            public bool MoveNext()
            {
                if (_position < _colors.Length - 1)
                {
                    _position++;
                    return true;
                }
    
                return false;
            }
    
            public void Reset()
            {
                _position = -1;
            }
        }
    
        class Spectrum : IEnumerable
        {
            private string[] Colors = {"violet", "blue", "cyan", "green", "yellow", "orange", "red"};
    
            public IEnumerator GetEnumerator()
            {
                return  new ColorEnumerator(Colors);
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                Spectrum spectrum = new Spectrum();
                foreach (var color in spectrum)
                {
                    Console.WriteLine(color);
                }
            }
        }
    }

    迭代器

    C#提供了更简单的创建枚举器和可枚举类型的方式

    //第一个代码
    public
    IEnumerator<string> BlackAndWhite() { yield return "black"; yield return "gray"; yield return "white"; }
    //第二个代码
    public IEnumerator<string> BlackAndWhite() { string[] theColors = {"black", "gray", "white"}; for (int i = 0; i < theColors.Length; i++) { yield return theColors[i]; } }

    迭代器块是有一个或多个yield语句的代码块

    它可以是:

    方法主体,访问器主体,运算符主体

    • yield return语句指定了序列中返回的下一项
    • yield break语句指定了在序列中没有其他项

    使用迭代器创建枚举器

     BlackAndWhite方法是一个迭代器块,可以为MyClass类产生返回枚举器的方法

    MyClass还实现了GetEnumerator方法,调用了BlackAndWhite并且返回BlackAndWhite返回的枚举器

    class MyClass
    {
        public IEnumerator<string> GetEnumerator()
        {
            return BlackAndWhite();
        }
    
        public IEnumerator<string> BlackAndWhite()
        {
            yield return "black";
            yield return "gray";
            yield return "white";
        }
    }

    使用迭代器创建可枚举类型

    public IEnumerator<string> GetEnumerator()
    {
        IEnumerable<string> myEnumerable = BlackAndWhite();//获取可枚举类型
        return myEnumerable.GetEnumerator();//获取枚举器
    }
    
    public IEnumerable<string> BlackAndWhite()
    {
        yield return "black";
        yield return "gray";
        yield return "white";
    }

  • 相关阅读:
    Codeforces Round #113 (Div. 2) Tetrahedron(滚动DP)
    Codeforces Round #300 Quasi Binary(DP)
    Codeforces Round #119 (Div. 2) Cut Ribbon(DP)
    Codeforces Round #260 (Div. 1) Boredom(DP)
    Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Cards Sorting(树状数组)
    Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Office Keys(思维)
    图灵杯 E 简单的RMQ(UVA 11235)(RMQ)
    qwb与学姐 (带秩并查集)
    计蒜客 UCloud 的安全秘钥(困难)(哈希)
    第八届山东省ACM大学生程序设计竞赛个人总结
  • 原文地址:https://www.cnblogs.com/yinghualuowu/p/9626142.html
Copyright © 2020-2023  润新知