先给出这两个接口的定义
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
public interface IEnumerator
{
object Current{get;}
bool MoveNext();
void Reset();
}
下面给出使用这两个接口,使得一个类可以使用foreach遍历的例子
public class IterationSample : IEnumerable
{
object[] values;
int startingPoint;
public IterationSample(object[] values, int startingPoint)
{
this.values = values;
this.startingPoint = startingPoint;
}
public IEnumerator GetEnumerator()
{
//return new IterationSampleIterator(this);
for (int index = 0; index < values.Length; index++)
{
yield return values[(index + startingPoint) % values.Length];
}
}
class IterationSampleIterator : IEnumerator
{
IterationSample parent;
int position;
internal IterationSampleIterator(IterationSample parent)
{
this.parent = parent;
this.position = -1;
}
public object Current
{
get
{
if (position == -1 || position == parent.values.Length)
{
throw new InvalidOperationException();
}
int index = (position + parent.startingPoint);
index = index % parent.values.Length;
return parent.values[index];
}
}
public bool MoveNext()
{
if (position != parent.values.Length)
{
position++;
}
return position < parent.values.Length;
}
public void Reset()
{
position = -1;
}
}
}
void Start()
{
string[] strArr = { "1", "2" };
IterationSample sample = new IterationSample(strArr, 0);
var iterator = sample.GetEnumerator();
while (iterator.MoveNext())
{
object item = iterator.Current;
Debug.Log(item);
}
foreach (var item in sample)
{
Debug.Log(item);
}
}
现在给出使用yield关键字语法糖简化后的代码
public class IterationSample : IEnumerable
{
object[] values;
int startingPoint;
public IterationSample(object[] values, int startingPoint)
{
this.values = values;
this.startingPoint = startingPoint;
}
public IEnumerator GetEnumerator()
{
for (int index = 0; index < values.Length; index++)
{
yield return values[(index + startingPoint) % values.Length];
}
}
}
从上面两个例子可以看出,yield return语法实际上在背后帮助我们定义了一个IEnumerator
我们再看一个例子
public static IEnumerable<int> EnumerableFunc()//这个函数会返回一个可枚举的容器对象,这个对象中包含若干用来枚举的项
{
yield return 1;
yield return 2;
yield return 3;
}
void Start()
{
IEnumerable<int> objIEnumerable = EnumerableFunc();
foreach (var item in objIEnumerable)
{
print("for each:" + item);
}
IEnumerator<int> objIEnumerator = objIEnumerable.GetEnumerator();
while (objIEnumerator.MoveNext())
{
print("while:" + objIEnumerator.Current);
}
}