众所周知,.net给我们提供了Foreach方法,让我们能够快速的遍历
那么他们内部的实现机制是什么呢?接下来我会提供给大家他的一.普通实现代码二.泛型实现代码,三.他的逻辑实现代码
一.实现一个普通的Foreach遍历(大家有的是,我就不写了,贴链接)
http://blog.youkuaiyun.com/dk_0520/article/details/68946830
代码在这里,大家通过上面的连接已经可以实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//你可以把这个方法理解成static void main方法,入口类
public class ForeachTest : MonoBehaviour
{
void Start()
{
Person[] persons = new Person[]
{
new Person("aaa", 20),
new Person("bbb", 21),
new Person("ccc", 22)
};
People peopleList = new People(persons);
foreach (var item in peopleList)
{
Debug.Log(item);
}
}
}
//我们自己写的一个属性类,只用来做测试
public class Person
{
string Name;
int Age;
public Person(string name, int age)
{
Name = name;
Age = age;
}
public override string ToString()
{
return "Name: " + Name + "\tAge: " + Age;
}
}
//我们写的实现简单迭代的类,他属于IEnumerator的儿子
public class PeopleEnum : IEnumerator
{
private Person[] _people;
int position = -1;
//构造方法
public PeopleEnum(Person[] list)
{
_people = list;
}
//将指针移动到下一个
public bool MoveNext()
{
position++;
return (position < _people.Length);
}
//清空方法,回到起点
public void Reset() { position = -1; }
//得到当前的对象
public object Current
{
get
{
return _people[position];
}
}
}
//通过这个方法调用PeopleEnum的东西,只有继承了IEnumerable才能使用foreach
public class People : IEnumerable
{
private Person[] _people;
public People(Person[] pArray)
{
_people = new Person[pArray.Length];
for (int i = 0; i < pArray.Length; i++)
{
_people[i] = pArray[i];
}
}
//只有实现这个方法才能使用foreach
public IEnumerator GetEnumerator()
{
Debug.Log("调用一次");
return new PeopleEnum(_people);
}
}
二.逻辑实现 大家通过上面的例子学完了可能感到很迷茫,虽然实现了,但是摸不着头脑,接下来,我们就按照他的逻辑给大家用代码的方式实现:
首先,因为是我们自己尝试实现这个过程,我们保留在上例中写的方法,但是我们将两个接口去掉:PeopleEnum : IEnumerator(去掉ienumerator)和People:IEnumerable
注意,只去掉继承关系,不去掉里面的方法,因为我们要模拟真正的实现过程
//你可以把这个方法理解成static void main方法,入口类
public class ForeachTest : MonoBehaviour
{
void Start()
{
Person[] persons = new Person[]
{
new Person("aaa", 20),
new Person("bbb", 21),
new Person("ccc", 22)
};
People peopleList = new People(persons);
//foreach (var item in peopleList)
//{
// Debug.Log(item);
//}
//上面的foreach会转换成一下形式
//得到一个peopleEnum,如同GetEnumerator
PeopleEnum p = new PeopleEnum(persons);
//判断是否进行下次
while (p.MoveNext())
{
//等同foreach 中的var item
var item =p.Current;
//执行语句
Debug.Log(item);
}
//结束语句
p.Reset();
//释放资源
}
}
三.泛型实现
相信大家都用过List<int>s = new List<int>();吧,那么接下来我们实现它其中的foreach循环遍历,注意他是泛型的哦
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyForeachTest : MonoBehaviour
{
void Start()
{
int[] t = new int[] { 3, 4, 5, 6, 7, 8 };
MyList<int> mps = new MyList<int>(t);
foreach (var item in mps)
{
Debug.Log(item);
}
}
}
public class MyPeople
{
public string love = "djfk";
public int life = UnityEngine.Random.Range(1, 111);
public override string ToString()
{
return love + life;
}
}
public class MyList<T> : IEnumerable<T>, IEnumerator<T>
{
private T[] arr;
private int index = -1;
public MyList(T[] arr) { this.arr = arr; }
public T Current
{
get
{
return arr[index];
}
}
object IEnumerator.Current
{
get
{
return arr[index];
}
}
//释放资源,我不会写,只能输出了
public void Dispose()
{
Debug.Log("dispose");
}
public IEnumerator<T> GetEnumerator()
{
return new MyList<T>(arr);
}
public bool MoveNext()
{
index++;
return index < arr.Length;
}
public void Reset()
{
index = -1;
}
IEnumerator IEnumerable.GetEnumerator()
{
return new MyList<T>(arr);
}
}