Unity C # вложенный IEnumerator - PullRequest
       2

Unity C # вложенный IEnumerator

2 голосов
/ 17 октября 2019

В моем коде у меня есть вложенные методы IEnumerator, такие как это:

    private IEnumerator PerformRequest(string url) {

        // Doing stuff

        UnityWebRequest request = UnityWebRequest.Get(url);
        yield return request.SendWebRequest();

        // Doing stuff
    }

    private IEnumerator PerformRequest2(string url) {

        // Doing stuff

        return PerformRequest(url);

        // Doing stuff
    }

    public IEnumerator PerformRequest3(string url) {

        // Doing stuff

        return PerformRequest2(url);

        // Doing stuff
    }

Мне интересно, в чем разница, если я добавлю yield в методы верхнего уровня, такие как это:

    private IEnumerator PerformRequest(string url) {

        // Doing stuff

        UnityWebRequest request = UnityWebRequest.Get(url);
        yield return request.SendWebRequest();

        // Doing stuff
    }

    private IEnumerator PerformRequest2(string url) {

        // Doing stuff

        yield return PerformRequest(url);

        // Doing stuff
    }

    public IEnumerator PerformRequest3(string url) {

        // Doing stuff

        yield return PerformRequest2(url);

        // Doing stuff
    }

Есть ли разница, или это то же самое поведение?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 17 октября 2019

Конечно, это работает

Я сделал что-то вроде этого раньше, вы можете абсолютно yield метод, который он сам по себе дает, потому что происходит то, что выполнение полностью линейный и когда PerformRequest возвращает и возвращает какое-то значение (веб-запрос, но на самом деле не важно), которое распространяется до yield return... в PerformRequest2, которое затем распространяется вверх до PerformRequest3. Unity возобновит выполнение в правильном месте просто отлично (и вы могли бы также ответить на свой вопрос, протестировав его;).

По сути, это то же самое, что и любая другая вложенная функция, например

int GetValue() {
    return 4;
}

int GetValue2() {
    return GetValue();
}

Выполняется точно так же, как (только с другим типом):

IEnumerator GetValue() {
    return new SomeIEnumerator();
}

IEnumerator GetValue2() {
    return GetValue();
}

, который преобразуется в результат сопрограммы (yield - это просто специальное ключевое слово, оно не влияет на тип возвращаемого значения!):

IEnumerator GetValue() {
    yield return new SomeIEnumerator();
}

IEnumerator GetValue2() {
    yield return GetValue();
}

Вы также можете сделать это следующим образом, но я обычно не могу найти в нем никакого значения:

IEnumerator GetValue() {
    yield return new SomeIEnumerator();
}

IEnumerator GetValue2() {
    //other stuff, with yield so our function still returns a value
    StarCoroutine(GetValue());
    //this stuff runs without waiting
}

Adassko также нашел этот замечательный урок о сопрограммах и вложенных сопрограммах.

0 голосов
/ 17 октября 2019

Стоит отметить, что в ответе Draco18s это:

IEnumerator GetValue() {
    // This line won't work.
    yield return new SomeIEnumerator();
}

IEnumerator GetValue2() {
    //other stuff, with yield so our function still returns a value
    StarCoroutine(GetValue());
    //this stuff runs without waiting
}

не будет работать, потому что вам нужно выдавать вложенную сопрограмму внутри вызова StartCoroutine, поэтому она должна быть:

IEnumerator GetValue() {
    // The corrected line.
    yield return StartCoroutine(SomeIEnumerator());
}

IEnumerator GetValue2() {
    //other stuff, with yield so our function still returns a value
    StarCoroutine(GetValue());
    //this stuff runs without waiting
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...