c# 迭代器的使用

foreach遍历

在开发过程中,经常会对集合或者数组进行遍历,用foreach进行遍历是我们经常使用到的,大概的实现过程如下:

var strlist = new List<string> { "a", "b" };
foreach (var str in strlist )
  {
      Console.WriteLine(str);
  }

但实际上代码的执行过程是这样的:

var strlist = new List<string> {"a", "b"};
IEnumerator<string> enumeratorList = strlist .GetEnumerator();
while (enumeratorList.MoveNext())
{
    Console.WriteLine(enumeratorList.Current);
}

会发现有GetEnumerator()方法和IEnumerator类型,这就涉及到可枚举类型和枚举器的概念。

迭代器的实现

必须是继承了IEnumerable,IEnumerable< T>,IEnumerator,IEnumerator< T>才可以使用foreach进行迭代。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace one
{
    class Person : IEnumerable
    {
        string[] names = { "小林", "观慧", "李星云", "女帝" };
        public int Count { get { return names.Length; } }    //可以通过对象访问此属性

        public IEnumerator GetEnumerator()
        {
            return new MyClass(names); //实际上通过此方法就是返回一个可以实现循环的类的对象  
        }
    }
}

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace one
{
    class MyClass:IEnumerator
    {
        private string[] name;
        int index = -1;

        public MyClass(string[] names)//一个参数的构造函数,用来和要遍历的类的进行关联
        {
            name = names;
        }
        
        public object Current //获取当前索引的元素的值
        {
            get
            {
                if (index < 0||index>=name.Length) //准备状态是-1,开始循环了在MoveNext中加1
                {
                    return null;
                }
                else
                {
                    return name[index];
                }
            }
        }


        public bool MoveNext()
        {
            index++;  //每调用此方法就将索引往下+1
            if (index < name.Length)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        public void Reset()//重置状态,将下标移到数组的第一个元素的前面
        {
            index = -1;
        }
    }
}

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace one
{
    class Program
    {
        static void Main(string[] args)
        {
            Person p = new Person();
            foreach (string item in p)
            {
                Console.WriteLine(item);
            }
            //实际执行foreach就相当于执行下面几句话:
            Console.WriteLine("==================================================");
            IEnumerator p1 = p.GetEnumerator();
            while (p1.MoveNext())
            {
                string str = (string)p1.Current;
                Console.WriteLine(str);
            }
            Console.ReadKey();
        }
    }
}

测试了一下,感觉两者的性能差不多。

发布了15 篇原创文章 · 获赞 0 · 访问量 254

猜你喜欢

转载自blog.csdn.net/weixin_43839583/article/details/103427877