C# foreach 今生
1.编写自己的迭代器,和FCL迭代模式是对应.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EnumerableDemo { class Program { static void Main(string[] args) { //使用接口IMyEnumerable 代替MyList IMyenumerable list = new MyList(); //得到迭代器,在循环中针对迭代器编码,而不是集合MyList IMyEnumerator enumerator = list.GetEnumberator(); //方式一: for (int i = 0; i < list.Count; i++) { object current = enumerator.Current; enumerator.MoveNext(); } //方式二: while (enumerator.MoveNext()) { object current = enumerator.Current; } } } /// <summary> /// 要求所有的迭代器全部实现该接口 /// </summary> interface IMyEnumerator { bool MoveNext(); object Current { get; } } /// <summary> /// 要求所有的集合实现该接口 /// 客户端就可以针对该接口编码 /// 而无需关注具体的实现 /// </summary> interface IMyenumerable { IMyEnumerator GetEnumberator(); int Count { get; } } class MyList : IMyenumerable { object[] items = new object[10]; IMyEnumerator myEnumerator; public object this[int i] { get { return items[i]; } set { this.items[i] = value; } } public int Count { get { return items.Length; } } public IMyEnumerator GetEnumberator() { if(myEnumerator == null) { myEnumerator = new MyEnumerator(this); } return myEnumerator; } } class MyEnumerator : IMyEnumerator { int index = 0; MyList myList; public MyEnumerator(MyList myList) { this.myList = myList; } public object Current { get { return myList[index - 1]; } } public bool MoveNext() { if (index + 1 > myList.Count) { index = 1; return false; } else { index++; return true; } } } }
2.无论是for循环还是while循环,都是不简洁的.于是foreach就诞生了.它用于遍历继承了IEnumerable或IEnumerable<T>接口的集合元素.
foreach(var x in xx){}
foreach循环除了可以提供简化的语法外,还有两个优势:
-1自动将代码置入try-finally块.
-2若类型实现了IDispose接口,它会在循环结束后自动调用Dispose方法.
反编译可以看到内部是:
using(List<object>.Enumerator CS$5$0000 =list.GetEnumerator())
{
while(CS$5$000.MoveNext())
{
object current = CS$5$0000.Current;
}
}
浙公网安备 33010602011771号