文档
关键内容
- 普通接口
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
- 泛型接口
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T> : IEnumerator, IDisposable
{
T Current { get; }
}
- yield return
使用yield return可简化迭代器的生成,不需要自己手动创建类进行实现。
注意:使用yield return生成的迭代器,无法使用Reset。
如需Reset,可自定义迭代器类,进行实现。
示例
TransformForeach1实现泛型接口IEnumerable,自己实现迭代器
TransformForeach2实现泛型接口IEnumerable,使用yield return实现迭代器
对比得知:yield return 可方便的简化迭代器生成
注意:如果实现泛型版本接口,yield return 返回类型要和泛型指定的类型一致
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test04 : MonoBehaviour
{
TransformForeach1 foreachTransform1;
IEnumerator<Transform> ator1;
TransformForeach2 foreachTransform2;
IEnumerator<Transform> ator2;
void Start()
{
int childCount = 5;
for (int i = 0; i < childCount; i++)
{
var obj = new GameObject(i.ToString());
obj.transform.SetParent(transform);
}
foreachTransform1 = new TransformForeach1(transform);
ator1 = foreachTransform1.GetEnumerator();
foreachTransform2 = new TransformForeach2(transform);
ator2 = foreachTransform2.GetEnumerator();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
//使用类实现泛型迭代器接口 可使用Reset方法
Debug.Log("1...");
while (ator1.MoveNext())
{
Debug.Log(ator1.Current);
}
ator1.Reset();
foreach (var item in foreachTransform1)
{
Debug.Log(item);
}
Debug.Log("2...");
//使用yield return实现泛型迭代器接口,无法使用Reset方法
try
{
while (ator2.MoveNext())
{
Debug.Log(ator2.Current);
}
ator2.Reset();
}
catch (System.Exception e)
{
Debug.LogException(e);
}
foreach (var item in foreachTransform2)
{
Debug.Log(item);
}
}
}
private class TransformForeach1 : IEnumerable<Transform>
{
Transform transform;
public TransformForeach1(Transform transform)
{
this.transform = transform;
}
public IEnumerator<Transform> GetEnumerator()
{
return new Enumerator(transform);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private class Enumerator : IEnumerator<Transform>
{
int index = -1;
Transform transform;
public Enumerator(Transform transform)
{
this.transform = transform;
}
public Transform Current => transform.GetChild(index);
object IEnumerator.Current => Current;
public void Dispose()
{
}
public bool MoveNext()
{
var childCount = transform.childCount;
return ++index < childCount;
}
public void Reset()
{
index = -1;
}
}
}
private class TransformForeach2 : IEnumerable<Transform>
{
Transform transform;
public TransformForeach2(Transform transform)
{
this.transform = transform;
}
public IEnumerator<Transform> GetEnumerator()
{
var length = transform.childCount;
for (int i = 0; i < length; i++)
yield return transform.GetChild(i);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}