Каков эквивалентный синтаксис в VB.NET для “возврата урожая”? [дубликат]

6
задан Peter Mortensen 23 April 2013 в 20:38
поделиться

5 ответов

Нет. Период. Если вы не собираетесь писать свой собственный конечный автомат, быстрого решения этой проблемы нет. См. Сообщение в блоге VB.NET "yield return" .

Для тех, кто заботится о том, что на самом деле сгенерировано (да, я люблю прекомпилятор и компилятор C # :)):

Попробуйте скомпилировать это и взгляните на сгенерированный код с помощью .NET Reflector или что-то в этом роде:

class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo();

        foreach(var result in foo.Bar())
        {
            Console.WriteLine(result);
        }

        Console.ReadLine();
    }
}

class Foo
{
    public IEnumerable<char> Bar()
    {
        const char start = 'a';

        for(int x = 0;x < 26;x++)
        {
            yield return (char)(start + x);
        }
    }
}

Я не собираюсь копировать результат, он огромен. Но посмотрите, и вы увидите, что решить эту задачу непросто.

16
ответ дан 9 December 2019 в 20:40
поделиться

Блок кода с операторами yield return / yield break называется итератором . Этой функции нет в VB. Конечно, этот код можно «перевести», но это не очень просто ... вам нужно создать собственный класс, реализующий IEnumerator (Of Integer) , чтобы воспроизвести точно такое же поведение:

  • Инициализируйте его параметрами исходной функции
  • . Реализуйте логику «цикла» в методе MoveNext , сохраняя переменные цикла в закрытых полях. Этот метод также должен установить поле для хранения текущего значения ( n в исходной функции)
  • Вернуть текущее значение из свойства Current
  • Сбросить переменные цикла в метод Reset
  • Ничего не делать в методе Dispose

Это выполнимо, но, честно говоря, это больно ...

Другой, более простой вариант - заполнить список (целых чисел) с результатами и возврат этого списка: просто замените yield return n на list.Add (n)

3
ответ дан 9 December 2019 в 20:40
поделиться

Нет. Однако вы можете создать его.
Создайте класс итератора.
Несколько шагов для этого:

  1. Создайте функцию, которая, по сути, является шагом в итерации. Функция должна принимать любые аргументы, необходимые для каждого вычисления, и возвращать аргументы для следующего вычисления. (чтобы реализовать yield break, а также yield return, эта функция должна также иметь возможность возвращать некоторое логическое значение, обозначающее конец)
  2. Создайте класс, реализующий IEnumerator. Свойство Current должно возвращать последнее вычисленное значение, Reset должно сбрасывать все значения до их начальных, а функция MoveNext должна вычислять следующее значение, а если вычислительная функция возвращает ложь, сама возвращает ложь.

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

1
ответ дан 9 December 2019 в 20:40
поделиться

В VB.NET нет эквивалента yield return, но его можно эмулировать.

См. вопрос Stack Overflow Yield в VB.NET и ответы на него.

Возможно, статья Visual Studio Magazine Use Iterators in VB Now поможет.

1
ответ дан 9 December 2019 в 20:40
поделиться

Точного дубликата yield в VB не существует. Лучше всего будет создать коллекцию, которая будет yielded, и вернуть ее целиком, чтобы вызывающий код мог выполнить итерацию. Это не совсем то же самое, что и приведенный вами код, но общий эффект должен быть таким же. yield - это, по сути, просто синтаксический сахар для возврата частей коллекции в цикл foreach по одной за раз для оптимизации времени выполнения и возможности раннего выхода из цикла (если вы решите, что вам не нужно перечислять все подряд).

3
ответ дан 9 December 2019 в 20:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: