协程中值为true后无法返回字符串

时间:2019-12-20 07:14:27

标签: c# unity3d return coroutine

我需要运行此协程,但遇到问题。它一直吐出一个错误,提示它无法将WaitUntil转换为字符串,并且当我将WaitUntil添加到返回类型时,它吐出另一个错误,提示它无法返回。我已经尝试研究了几个小时,但无济于事。这是代码段:

     public string OpenSaveDialog(string Title, string OpenLocation, string[] AllowedExtentions)
     {
         OpenBtn.GetComponentInChildren<TMPro.TMP_Text>().text = "Save";
         TitleText.text = Title;
         AllowFileNameTyping = true;
         MultiSelect = false;

         LoadIntoExplorer(PathInput, AllowedExtentions);

         return StartCoroutine(WaitForFinish()); // Error here: Cannot implicitly convert type 'UnityEngine.Coroutine' to 'string'
     }

     IEnumerator<string> WaitForFinish()
     {
         yield return new WaitUntil(() => Done == true); // Error here: Cannot implicitly convert type 'UnityEngine.WaitUntil' to 'string'
         yield return FilePathsSelected[0];
     }

2 个答案:

答案 0 :(得分:7)

您无法从协程返回值,您的选项正在制作回调,类范围变量,该变量指示具有IsDone&value或result属性的协程,自定义类的值,也不能使用ref,输入或输出关键字也是如此,因为迭代器无法使用它们:/,所以这行不通:

public IEnumerator WaitForFinnish(ref string value)
{
    yield return new WaitUntil(() => true);
    value = "value";
}

所以在您的情况下,我会做这样的事情:

string filePath = string.Empty;

public void OpenSaveDialog(string Title, string OpenLocation, string[] AllowedExtentions)
{
     OpenBtn.GetComponentInChildren<TMPro.TMP_Text>().text = "Save";
     TitleText.text = Title;
     AllowFileNameTyping = true;
     MultiSelect = false;

     LoadIntoExplorer(PathInput, AllowedExtentions);

     StartCoroutine(WaitForFinish());
 }

 IEnumerator WaitForFinish()
 {
     yield return new WaitUntil(() => Done); // Also don't do bool == true or false,
                                             // it will trigger most of the programmers :D
     filePath = FilePathsSelected[0];
 }

答案 1 :(得分:4)

添加到Menyus' answer

我宁愿使用回调方法

public void OpenSaveDialog(string Title, string OpenLocation, string[] AllowedExtentions, Action<string> whenDone = null)
 {
     OpenBtn.GetComponentInChildren<TMPro.TMP_Text>().text = "Save";
     TitleText.text = Title;
     AllowFileNameTyping = true;
     MultiSelect = false;

     LoadIntoExplorer(PathInput, AllowedExtentions);

     StartCoroutine(WaitForFinish(whenDone));
 }

 IEnumerator WaitForFinish(Action<string> whenDone)
 {
     yield return new WaitUntil(() => Done);

     whenDone?.Invoke(FilePathsSelected[0]);
 }

因此,现在无论何时调用该方法,您都可以传递一个应在完成时执行的动作,例如

// as lambda expression
OpenSaveDialog("Title", "Some/Path", new []{ ".example" }, path =>
    {
        Debug.Log($"The selected path is {path}");
    });

//Or with a dedicated method 
OpenSaveDialog("Title", "Some/Path", new []{ ".example" }, OnPathSelected);

...

private void OnPathSelected (string path)
{
    Debug.Log($"The selected path is {path}");
}

当然,我们看不到LoadIntoExplorer的确切作用。也许您甚至可以完全跳过协程,而改为向该方法添加Action<string>回调?