//继承IEnumerable接口,其实也可以不继承这个接口,只要类里面含有返回IEnumberator引用的GetEnumerator()方法即可
class ForeachTest : IEnumerable
{
private string[] elements; //装载字符串的数组
private int ctr = 0; //数组的下标计数器
///
/// 初始化的字符串
///
///
ForeachTest(params string[] initialStrings)
{
//为字符串分配内存空间
elements = new String[8];
//复制传递给构造方法的字符串
foreach (string s in initialStrings)
{
elements[ctr++] = s;
}
}
///
/// 构造函数
///
/// 初始化的字符串
/// 分隔符,可以是一个或多个字符分隔
ForeachTest(string initialStrings, char[] delimiters)
{
elements = initialStrings.Split(delimiters);
}
//实现接口中得方法
public IEnumerator GetEnumerator()
{
return new ForeachTestEnumerator(this);
}
private class ForeachTestEnumerator : IEnumerator
{
private int position = -1;
private ForeachTest t;
public ForeachTestEnumerator(ForeachTest t)
{
this.t = t;
}
#region 实现接口
public object Current
{
get
{
return t.elements[position];
}
}
public bool MoveNext()
{
if (position < t.elements.Length - 1)
{
position++;
return true;
}
else
{
return false;
}
}
public void Reset()
{
position = -1;
}
#endregion
}
}
class MainEntry
{
static int frame = 0;
static public IEnumerator WaitCoroutine()
{
Console.WriteLine("begin");
yield return null;
Console.WriteLine("Coroutine{0}", frame);
yield return new WaitFream(10);
Console.WriteLine("Coroutine{0}", frame);
yield return null;
Console.WriteLine("end");
}
//协程迭代5帧
static public IEnumerator CoroutineDo5Frame()
{
while (true)
{
if(frame >= 5)
{
break;
}
Console.WriteLine("CoroutineTick");
yield return null;
}
}
//等待给定帧数
class WaitFream
{
int wait_count = 0;
public WaitFream(int count)
{
wait_count = count;
}
public bool Tick()
{
return --wait_count > 0;
}
}
static LinkedList CoroutineList = new LinkedList();
static void StartCoroutine(IEnumerator enumerator)
{
CoroutineList.AddLast(enumerator);
}
static void CoroutineTick()
{
var node = CoroutineList.First;
while(node != null)
{
IEnumerator cur_etor = node.Value;
bool ret = true;
if (cur_etor.Current is WaitFream)
{
WaitFream wf = (WaitFream)cur_etor.Current;
if (!wf.Tick())
{
ret = cur_etor.MoveNext();
}
}
else
{
ret = cur_etor.MoveNext();
}
//删除节点
if(ret == false)
{
CoroutineList.Remove(node);
}
node = node.Next;
}
}
static void Main(string[] args)
{
// ForeachTest f = new ForeachTest("This is a sample sentence.", new char[] { ' ', '-' });
StartCoroutine(WaitCoroutine());
StartCoroutine(CoroutineDo5Feam());
while (true)
{
frema++;
Console.WriteLine("trunk loop frame:{0}", frame);
CoroutineTick();
Console.ReadLine();
}
}
}
}
仅仅是一个语法糖,用switch case 将不同yiled之间的代码块隔开,movenext时执行代码块并且改变到下一个执行状态,下次执行时将执行下一个代码块,将yield后面的值赋值给current值
反编译语法糖展开代码
class Program
{
static void Main(string[] args)
{
//这儿调用了方法。
var test = Power(2, 8, "");
Console.WriteLine("Begin to iterate the collection.");
//Display powers of 2 up to the exponent of 8:
foreach (int i in Power(2, 8, ""))
{
Console.Write("{0} ", i);
}
Console.ReadKey();
}
public static IEnumerable<int> Power(int number, int exponent, string s)
{
int result = 1;
if (string.IsNullOrEmpty(s))
{
Console.WriteLine("Begin to invoke GetItems() method");
}
for (int i = 0; i < exponent; i++)
{
result = result * number;
yield return result;
}
yield return 3;
yield return 4;
yield return 5;
}
}
namespace ConsoleApplication2
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
internal class Program
{
private static void Main(string[] args)
{
IEnumerable<int> enumerable = Power(2, 8, "");
Console.WriteLine("Begin to iterate the collection.");
foreach (int num in Power(2, 8, ""))
{
Console.Write("{0} ", num);
}
Console.ReadKey();
}
public static IEnumerable<int> Power(int number, int exponent, string s)
{
d__0 d__ = new d__0(-2);
d__.<>3__number = number;
d__.<>3__exponent = exponent;
d__.<>3__s = s;
return d__;
}
[CompilerGenerated]
private sealed class d__0 : IEnumerable<int>, IEnumerable, IEnumerator<int>, IEnumerator, IDisposable
{
private int <>1__state;
private int <>2__current;
public int <>3__exponent;
public int <>3__number;
public string <>3__s;
private int <>l__initialThreadId;
public int 5__2;
public int 5__1;
public int exponent;
public int number;
public string s;
[DebuggerHidden]
public d__0(int <>1__state)
{
this.<>1__state = <>1__state;
this.<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
private bool MoveNext()
{
switch (this.<>1__state)
{
case 0:
this.<>1__state = -1;
this.5__1 = 1;
if (string.IsNullOrEmpty(this.s))
{
Console.WriteLine("Begin to invoke GetItems() method");
}
this.5__2 = 0;
while (this.5__2 < this.exponent)
{
this.5__1 *= this.number;
this.<>2__current = this.5__1;
this.<>1__state = 1;
return true;
Label_009D:
this.<>1__state = -1;
this.5__2++;
}
this.<>2__current = 3;
this.<>1__state = 2;
return true;
case 1:
goto Label_009D;
case 2:
this.<>1__state = -1;
this.<>2__current = 4;
this.<>1__state = 3;
return true;
case 3:
this.<>1__state = -1;
this.<>2__current = 5;
this.<>1__state = 4;
return true;
case 4:
this.<>1__state = -1;
break;
}
return false;
}
[DebuggerHidden]
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
Program.d__0 d__;
if ((Environment.CurrentManagedThreadId == this.<>l__initialThreadId) && (this.<>1__state == -2))
{
this.<>1__state = 0;
d__ = this;
}
else
{
d__ = new Program.d__0(0);
}
d__.number = this.<>3__number;
d__.exponent = this.<>3__exponent;
d__.s = this.<>3__s;
return d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return this.System.Collections.Generic.IEnumerable.GetEnumerator();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
void IDisposable.Dispose()
{
}
int IEnumerator<int>.Current
{
[DebuggerHidden]
get
{
return this.<>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return this.<>2__current;
}
}
}
}
}
才疏学浅,欢迎指正