IEnumerable接口实现

1.下面代码基本实现foreach代码基本实现。

2.Tolist延迟加载原理。

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

namespace ConsoleApp1.MyEnumerable
{

    public class TestEnumerabel
    {
        public static void Run()
        {
            string[] arr = new string[] { "a", "ba", "cc", "da", "e" };
            MyIEnumerable myEnumerable = new MyIEnumerable(arr);
            var items = myEnumerable.GetEnumerator();
            while (items.MoveNext())
            {
                Console.WriteLine(items.Current);
            }

            Console.WriteLine("============");

            //foreach遍历条件,需要实现GetEnumerator方法就可以
            foreach (var item in myEnumerable)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("============");

            //yield迭代器实现:反编译会发现yield其实就是实现了上面代码
            YieldEnumerable y = new YieldEnumerable(arr);
            var items1 = y.GetEnumerator();
            while (items1.MoveNext())
            {
                Console.WriteLine(items1.Current);
            }

            Console.WriteLine("============");
            var list1 = y.MyWhere(x => x.Contains("a"));
            var items11 = list1.GetEnumerator();
            //类似Tolist实现,在MoveNext时候才会去执行where真实过滤,实现延迟加载。
            while (items11.MoveNext())
            {
                Console.WriteLine(items11.Current);
            }
        }
    }

    public class MyIEnumerable : IEnumerable
    {
        private string[] strList;
        public MyIEnumerable(string[] strList)
        {
            this.strList = strList;
        }
        public IEnumerator GetEnumerator()
        {
            return new MyEnumerator(strList);
        }
    }

    public class MyEnumerator : IEnumerator
    {
        private string[] strList;
        private int position;

        public MyEnumerator(string[] strList)
        {
            this.strList = strList;
            position = -1;
        }
        public object Current
        {
            get { return strList[position]; }
        }

        public bool MoveNext()
        {
            position++;
            if (position < strList.Length)
            {
                return true;
            }
            return false;
        }

        public void Reset()
        {
            position = -1;
        }
    }

    public class YieldEnumerable:IEnumerable<string>,IEnumerable
    {
        private string[] strList;
        public YieldEnumerable(string[] strList)
        {
            this.strList = strList;
        }
        public IEnumerator GetEnumerator()
        {
            for (int i = 0; i < strList.Length; i++)
            {
                yield return strList[i];
            }
        }

        public IEnumerable<string> MyWhere(Func<string,bool> func)
        {
            foreach (string item in this)
            {
                if (func(item))
                {
                    yield return item;
                }
            }
        }

        IEnumerator<string> IEnumerable<string>.GetEnumerator()
        {
            for (int i = 0; i < strList.Length; i++)
            {
                yield return strList[i];
            }
        }
    }
}
原文地址:https://www.cnblogs.com/zhuyapeng/p/13671456.html