zoukankan      html  css  js  c++  java
  • 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";
    }

  • 相关阅读:
    June. 26th 2018, Week 26th. Tuesday
    June. 25th 2018, Week 26th. Monday
    June. 24th 2018, Week 26th. Sunday
    June. 23rd 2018, Week 25th. Saturday
    June. 22 2018, Week 25th. Friday
    June. 21 2018, Week 25th. Thursday
    June. 20 2018, Week 25th. Wednesday
    【2018.10.11 C与C++基础】C Preprocessor的功能及缺陷(草稿)
    June.19 2018, Week 25th Tuesday
    June 18. 2018, Week 25th. Monday
  • 原文地址:https://www.cnblogs.com/yinghualuowu/p/9626142.html
Copyright © 2011-2022 走看看