2016-09-23 20 views
-1

我尝试过搜索,但在介绍协同例程系统的所有主题之间丢失了,但没有详细说明。我已经知道StartCoroutine返回一个协程序,所以我试着寻找是否有某种隐式运算符为无效返回类型重载,甚至尝试过,但它没有工作,我什么也没找到。老实说,我能想到的,你可以告诉我是初学者 这个问题没有具体的目标,我只是真的很感兴趣。在此先感谢Unity的StartCoroutine如何使用和不使用任务?

编辑:我很抱歉没有让我的问题明确: 如何能说StartCoroutine(example());Coroutine myCoroutine = StartCoroutine(example())?如果返回类型是协程,第一个如何工作就像一个void?

+5

我不能为了我的生活找出你在这里问的问题。你能给一个代码示例说明什么让你感到困惑吗? –

回答

7

比较

StartCoroutine(example()); 

Coroutine myCoroutine = StartCoroutine(example()); 

如何像一个void的第一个工作,如果返回类型为Coroutine

你已经把规则倒过来了。 C#中的规则不是“一个非void方法必须分配或使用它的返回值。”规则是相反的:一个void方法只能用作一个语句。

如果您使用非void方法作为语句,编译器会生成放弃返回值的代码。

是否是智能要做或不做的事情不是编译器决定的。

然而,只有某些表达式可以用作语句的情况下;不太令人吃惊,它们是那些对其副作用有用的表达。它们是:

  • 方法调用
  • 分配(是的,分配是表达式)
  • 递增/递减
  • 构造函数调用( “新”) - 这是罕见的
  • 等待

所以你可以这样说:

M(); 
x = 123; 
x++; 
new Abc(); 
await someTask; 

但不是

2 + 2; 
(string)M(); 

等。

+2

埃里克,我不知道你是否做Unity3d,但只是想给你一个头脑,说明Unity可以在.NET 2.0 PCL上运行,并带有像Linq一样的3.5个细节。所以你不能使用异步/等待它(仍然upvoted你的答案,因为它是非常好的,只是不想让你专注于异步/等待一个unity3d问题太多)。 –

+0

@ScottChamberlain:好的,谢谢!太糟糕了,因为显然等待使得处理协程更容易。 –

+0

Unity将'yield return'的自动实现的迭代器偷走,而不是因为它早在C#5之前就出现了。我希望当他们切换到netstandard时,他们开始允许我们使用async/await而不是yield返回特殊的['YieldInstruction'](https://docs.unity3d.com/ScriptReference/YieldInstruction.html)派生类。 –

3

您并不总是需要保存具有返回值的函数的结果。如果你没有

public void Awake() 
{ 
    Foo(); 
} 

private int Foo() 
{ 
    return 42; 
} 

编译器没有问题。

原因StartCoroutine返回任何东西,如果你想做嵌套的协同程序,并且你想等待内部例程完成,然后继续外部。

这里是一个例子,其中房间在游戏中动态加载,一旦第一个房间被加载,玩家被允许移动,然后附加房间在之后依次加载。

private bool _allowPlayerMovement; 

public Room FirstRoom; 
public Room SecondRoom; 
public Room ThirdRoom; 
//... 

public void Awake() 
{ 
    _allowPlayerMovement = false; 
    StartCoroutine(LoadRooms()) 
} 

private IEnumerator LoadRooms() 
{ 
    //Runs the LoadFirstRoom Coroutine then waits for it to finish. 
    yield return StartCoroutine(LoadFirstRoom()) 

    //One the first routine finishes set the variable to true. 
    _allowPlayerMovement = true; 

    //Start loading the 2nd room, wait for it to finish 
    yield return StartCoroutine(LoadSecondRoom()) 

    //Once the 2nd room is finished loading start loading the 3rd room. 
    yield return StartCoroutine(LoadThirdRoom()) 

    //... And so on 
} 

private IEnumerator LoadFirstRoom() 
{ 
    WWW www = new WWW("http:\\example.com\levels\FirstRoom.json") 
    yield return www; 
    FirstRoom = JsonUtility.FromJson<Room>(www.text); 
} 

//... And so on 

如果你不在乎当协程“完成”就没有必要从StartCoroutine保存结果(就像在我上面的例子中的Awake功能)

+0

“如果你不关心Coroutine何时”结束“,那么就没有必要保存StartCoroutine的结果”它认为OP正在寻找 – Programmer

+1

@Programmer我也这么认为,我只是想包括一个例子什么时候你会关心它也完成了。 –

+0

谢谢,斯科特!我实际上意识到这一点,并且一直在使用协程,只是对我刚刚学到的这个事实感兴趣:表达式可以用作语句。我认为它需要一些特殊的实现,比如隐式运算符重载,但现在都清楚了,谢谢! –