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]; } } } }