迭代器模式
简单理解,循环的特殊版本。
C# 定义的迭代器接口
csharp
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
"容器类"实现IEnumerable(枚举)接口,返回迭代器。
利用迭代器可遍历容器中的元素。
MoveNext类似for循环的条件语句,判断循环是否可以继续执行。
Curren获取当前遍历的元素。
Reset重置循环。
Transform类的实现
实现IEnumerable接口,返回迭代器。
csharp
public class Transform : Component, IEnumerable
{
public IEnumerator GetEnumerator()
{
return new Enumerator(this);
}
}
Enumerator类实现IEnumerator接口,可遍历Transform的子节点
csharp
public class Transform : Component, IEnumerable
{
private class Enumerator : IEnumerator
{
private Transform outer;
private int currentIndex = -1;
public object Current => outer.GetChild(currentIndex);
internal Enumerator(Transform outer)
{
this.outer = outer;
}
public bool MoveNext()
{
int childCount = outer.childCount;
return ++currentIndex < childCount;
}
public void Reset()
{
currentIndex = -1;
}
}
}
示例程序
Start:
构建两个游戏对象,设置父对象。
获取transform的枚举接口和迭代器接口。
Update:
按下空格键,使用两种方式打印transform的子对象
方式1:利用while和迭代器进行遍历。
优点:复用迭代器;缺点:语法复杂。
方式2:利用foreach进行遍历。
优点:语法简洁。缺点:遍历前,foreach会调用枚举接口返回一个迭代器对象。
csharp
using System.Collections;
using UnityEngine;
public class Test03 : MonoBehaviour
{
IEnumerable able;
IEnumerator ator;
private void Start()
{
for (int i = 0; i < 2; i++)
{
var obj = new GameObject(i.ToString());
obj.transform.SetParent(transform);
}
able = transform;
ator = able.GetEnumerator();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
while (ator.MoveNext()) //方式1
Debug.Log(ator.Current);
ator.Reset();
foreach (Transform item in able)//方式2
{
Debug.Log(item);
}
}
}
}