Могу ли я реализовать yield return для функций IEnumerable в VB.NET?

Возможный дубликат:
доходность в VB.NET

В C # при написании функции, возвращающей IEnumerble<>, вы можете использовать yield return для возврата одного элемента перечисления и yield break; для обозначения отсутствия оставшихся элементов. Каков синтаксис VB.NET для того же?

Пример из кода NerdDinner:

public IEnumerable<RuleViolation> GetRuleViolations() {

   if (String.IsNullOrEmpty(Title))
       yield return new RuleViolation("Title required","Title");

   if (String.IsNullOrEmpty(Description))
       yield return new RuleViolation("Description required","Description");

   if (String.IsNullOrEmpty(HostedBy))
       yield return new RuleViolation("HostedBy required", "HostedBy");

   if (String.IsNullOrEmpty(Address))
       yield return new RuleViolation("Address required", "Address");

   if (String.IsNullOrEmpty(Country))
       yield return new RuleViolation("Country required", "Country");

   if (String.IsNullOrEmpty(ContactPhone))
       yield return new RuleViolation("Phone# required", "ContactPhone");

   if (!PhoneValidator.IsValidNumber(ContactPhone, Country))
       yield return new RuleViolation("Phone# does not match country", "ContactPhone");

   yield break;
}

Этот инструмент преобразования C # в VB.NET дает сообщение "YieldStatement is неподдерживаемая "ошибка.


person CoderDennis    schedule 17.05.2009    source источник
comment
Обратите внимание, что уступка не возвращается, по крайней мере, не в том смысле, в котором большинство людей имеет в виду возвращение (несмотря на то, как это реализовано под капотом). Кроме того, здесь не требуется перерыв в урожайности. Кроме того, вы можете подумать о преобразовании этого кода из перечисления объектов RuleViolation в перечисление делегатов Func ‹MyModelClass, RuleViolation›.   -  person yfeldblum    schedule 18.05.2009
comment
Использование yield напоминает мне конвейер, в котором вызывающий код может начать итерацию через ienumerable до завершения работы функции, возвращающей ienumerable. Очень круто!   -  person Neil Trodden    schedule 18.05.2009
comment
Это ужасный пример, потому что вам явно не нужна прибыль для чего-то вроде этого: какая польза от ленивого определения нарушений правил? Сложите их все в список и покончите с этим. Это не значит, что yeild бесполезен, но это просто плохой пример.   -  person piers7    schedule 14.08.2009
comment
@ piers7, с тех пор, как я разместил этот вопрос, я узнал намного больше о yield и итераторах, и мне придется согласиться с вами. Это было первое место, где я увидел yield, поэтому я включил этот пример. Лучший пример, который я видел на сегодняшний день, - это генератор простых чисел, у которого нет предустановленного предела размера (кроме MaxInt, конечно).   -  person CoderDennis    schedule 14.08.2009
comment
Вау, через 5 минут использования VB я столкнулся с серьезной проблемой. Интересно, чего еще не хватает. Хотя я не использую yield return каждый день, я использую функции, которые он позволяет мне писать каждый день. Я собираюсь сказать руководству, что я не использую VB для этого :-) Я думал, что VB должен был догнать C #.   -  person MikeKulls    schedule 02.02.2012
comment
Что касается piers7, я не уверен, что это такой уж плохой пример. Он оценивает условия по мере необходимости и останавливается, если все, что потребляет, останавливается.   -  person MikeKulls    schedule 06.02.2012


Ответы (6)


В настоящее время в VB.Net нет эквивалента доходности C # на уровне синтаксиса языка.

Однако недавно в журнале MSDN Билл Маккарти написал о том, как реализовать аналогичный шаблон в VB.Net 9.0.

person JaredPar    schedule 17.05.2009

Новый Async CTP включает поддержку Yield в VB.NET.

См. Итераторы в Visual Basic для получения информации об использовании.

person CoderDennis    schedule 05.05.2011

Смотрите мои ответы здесь:

Подводя итог:
VB.Net не имеет yield, но C # реализует yield, преобразовывая ваш код в конечный автомат за кулисами. Ключевое слово Static в VB.Net также позволяет сохранять состояние внутри функции, поэтому теоретически вы должны иметь возможность реализовать класс, который позволяет писать аналогичный код при использовании в качестве Static члена метода.

person Joel Coehoorn    schedule 17.05.2009

Нет возврата доходности в VB.NET :( Просто создайте список и верните его.

person bbmud    schedule 17.05.2009

За кулисами компилятор создает класс перечислителя для выполнения этой работы. Поскольку VB.NET не реализует этот шаблон, вам необходимо создать свою собственную реализацию IEnumerator (Of T).

person Thomas Levesque    schedule 17.05.2009

Ниже приведены результаты: 2, 4, 8, 16, 32

In VB,

Public Shared Function setofNumbers() As Integer()

    Dim counter As Integer = 0
    Dim results As New List(Of Integer)
    Dim result As Integer = 1
    While counter < 5
        result = result * 2
        results.Add(result)
        counter += 1
    End While
    Return results.ToArray()
End Function

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    For Each i As Integer In setofNumbers()
        MessageBox.Show(i)
    Next
End Sub

In C#

   private void Form1_Load(object sender, EventArgs e)
    {
        foreach (int i in setofNumbers())
        {
            MessageBox.Show(i.ToString());
        }
    }

    public static IEnumerable<int> setofNumbers()
    {
        int counter=0;
        //List<int> results = new List<int>();
        int result=1;
        while (counter < 5)
        {
          result = result * 2;
          counter += 1;
          yield return result;
        }
    }
person meenakshisundaram muthukrishna    schedule 02.05.2011
comment
Да, для этого простого примера это сработает. Есть и другие лучшие примеры итераторов, в которых вы не хотите или не можете создавать весь список за один вызов функции. Ваш код C # вычисляет каждое значение только тогда, когда вы используете их в цикле foreach. Код VB вычисляет все значения, когда вы вызываете функцию setOfNumbers. Это существенная разница. - person CoderDennis; 04.05.2011