在 Unity3d 中使用 IEnumerator 与 IEnumerable 的嵌套协程

Kyl*_*e G 5 c# iterator coroutine unity-game-engine

我正在使用Unity3D的 StartCoroutine 方法,我有一个关于嵌套协程的问题。

通常,嵌套协程可能如下所示:

void Start() { StartCoroutine(OuterCoroutine()); }

IEnumerator OuterCoroutine()
{
    //Do Some Stuff . . .
    yield return StartCoroutine(InnerCoroutine());
    //Finish Doing Stuff . . .
}

IEnumerator InnerCoroutine()
{
    //Do some other stuff . . .
    yield return new WaitForSeconds(2f);
    //Finish Doing that other stuff . . .
}
Run Code Online (Sandbox Code Playgroud)

这一切都很好,但真的没有必要。可以像这样实现相同的效果:

void Start() { StartCoroutine(OuterCoroutine()); }

IEnumerator OuterCoroutine()
{
    //Do Some Stuff . . .
    IEnumerator innerCoroutineEnumerator = InnerCoroutine().GetEnumerator();
    while(innerCoroutineEnumerator.MoveNext())
        yield return innerCoroutineEnumerator.Current;
    //Finish Doing Stuff . . .
}

IEnumerable InnerCoroutine()
{
    //Do some other stuff . . .
    yield return new WaitForSeconds(2f);
    //Finish Doing that other stuff . . .
}
Run Code Online (Sandbox Code Playgroud)

我发现这种方法产生的垃圾比有多个 StartCoroutines 少(这在 Unity 中可能是一个问题);因此它非常有用,尤其是在处理许多嵌套层时。

现在我的问题是:

而不是IEnumerable InnerCoroutine(){}像这样使用和获取枚举器:

IEnumerator innerCoroutineEnumerator = InnerCoroutine().GetEnumerator(); 
Run Code Online (Sandbox Code Playgroud)

我想像这样使用IEnumerator InnerCoroutine(){}和获取枚举器:

IEnumerator innerCoroutineEnumerator = InnerCoroutine();
Run Code Online (Sandbox Code Playgroud)

他们是一样的吗?

除了在我的测试中速度更快之外,此方法还允许我通过正常的 StartCoroutine 方法使用“内部协程”方法,这在未来可能会很有用。

我已经完成了测试,据我所知,这两种技术都在有效地做同样的事情,但我在整个编码方面仍然相对较新,所以我有可能遗漏了一些东西。

For*_*gic 3

事实上,两种书写方式都会产生相同的结果。

这更多是一个 C# 问题,Unity3D 只是在其协程系统中使用这些类型。您可能会发现这篇文章更详细地回答了您的问题。

但是,我不确定你的意思

我发现这种方法产生的垃圾更少(这可能是 Unity 中的一个问题)

因为两种方法应该产生相同的结果。此时更多的是代码风格的选择。

我个人更喜欢StartCoroutine(InnerCoroutine())one liner,它InnerCoroutine()会返回一个IEnumerator. 我不认为返回 IEnumerableInnerCoroutine()然后再获取其枚举器有什么意义。

  • 如果您计划手动 foreach 枚举器块的内容,则返回 IEnumerable 很方便,但同样,它只是语法糖,因为您可以使用 while (iterator.MoveNext()) {} 循环使用 IEnumerator 获得相同的结果。一个区别是,当使用 foreach 时,保证在 IEnumerable 上自动调用 Dispose,而 IEnumerator 则没有同样的好处。但尚不清楚这何时或如何变得有用。 (2认同)