原來這才是 IEnumerable 的存在意義.

////////
IEnumerable SpecialCollection()
{
//for (int i = 1; ; ++i) yield return i;
for (int i = 2; ; i += 2) yield return i;
}
////////
foreach (int i in SpecialCollection())
{
Console.Write(i + " ");
}

其實 IEnumerable 是一個 Interface .. 主要是希望做一個像 List 的一種存在. SpecialCollection() 是一個 Infinite loop, foreach 這個 List 則會回傳一個永遠不會完結的 loop. 所以使用 Unity3d 中的 Coroutine 是可以使用 yield return 去等待另一個 Coroutine 的執行緒. 而再進行下一步的工作. 到今天才明白 Coroutine 的根本結構.

IEnumerator Func1()
{
    Debug.Log("Func1 startup.");
    for (int i=0; i<10; i++)
    {
        yield return null;
    }
    Debug.Log("Func1 End.");
    yield break;
}
 
IEnumerator Func2()
{
    //wait for the completion of Func1
    Debug.Log("Func2 startup.");
    yield return StartCoroutine( Func1() );
    Debug.Log("Func2 End.");
}
Start()
{
    StartCoroutine(Func2());
}
/*
Result :
Func2 startup
Func1 startup
Func1 End
Func2 End
*/

這裡衍生了另一種寫法叫作 Nested coroutine .

IEnumerator Func2()
{
    //wait for the completion of Func1
    IEnumerator e = Func1();
    while (e.MoveNext()) yield return e.Current;
}

把整個 IEnumerator Func1 像 list 一樣代入 variable e.

使用 MoveNext() 去執行每個 cycle,

e.Current 則會回傳 Coroutine 裡 yield return 的 result.

使到 Func2 可以使用 Func1 裡的 yield return value 進行處理,

或者從 Func2 操控執行 Func1 的時機.

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

*

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料