Подтвердить что ты не робот

Итератор в VB.NET(С# будет использовать выход!)

Как реализовать шаблон итератора в VB.NET, который не имеет ключевого слова yield?

4b9b3361

Ответ 3

VB.NET не поддерживает создание пользовательских итераторов и, следовательно, не имеет эквивалента ключевому слову С# yield. Тем не менее, вы можете захотеть взглянуть на статью KB Как сделать класс Visual Basic.NET или Visual Basic 2005 пригодным для использования в инструкции для каждого пользователя для получения дополнительной информации.

Ответ 4

Хм, похоже, что вы можете из-за удачи:

Сегодня я боролся с проблемой при конвертации некоторых С# в VB.NET. С# имеет действительно классный оператор return return, который используется в блоке итератора для предоставления значения объекту перечислителя. У VB.NET нет ключевого слова "yield". Итак, есть несколько решений (ни одна из которых не очень чистая), чтобы обойти это. Вы можете использовать оператор return, чтобы вернуть значение, если вы зацикливаетесь и хотите разбить перечислитель и вернуть одно значение. Однако, если вы хотите вернуть все перечисление, создайте List() дочернего типа и верните список. Поскольку вы обычно используете это с IEnumerable, List() будет работать хорошо.

Это было написано год назад, не уверен, что с тех пор кто-то придумал что-нибудь еще.


Изменить: это будет возможно в версии 11 VB.NET(после VS2010), планируется поддержка итераторов. Спецификация доступна здесь.

Ответ 5

Ключевое слово

С# yield заставляет компилятор создать конечный автомат в фоновом режиме для его поддержки. У VB.Net нет ключевого слова yield. Но у него есть конструкция, которая позволит вам создать конечный автомат внутри функции: Элементы статической функции.

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

Это, конечно, потребует реализации класса вне функции. Но если все сделано правильно, класс должен быть повторно использован в общем случае. Я не играл с идеей, достаточной для предоставления каких-либо деталей реализации.

Ответ 6

Имейте в виду, что отложенное выполнение и ленивые оценочные свойства выражений и методов LINQ позволяют нам эффективно реализовывать пользовательские итераторы до тех пор, пока в .NET 4.5 не появится оператор yield. Доходность используется внутренне выражениями и методами LINQ.

Следующий код демонстрирует это.

    Private Sub AddOrRemoveUsersFromRoles(procName As String,
                                      applicationId As Integer,
                                      userNames As String(),
                                      rolenames As String())
    Dim sqldb As SqlDatabase = CType(db, SqlDatabase)
    Dim command As DbCommand = sqldb.GetStoredProcCommand(procName)
    Dim record As New SqlDataRecord({New SqlMetaData("value", SqlDbType.VarChar,200)})
    Dim setRecord As Func(Of String, SqlDataRecord) =
        Function(value As String)
            record.SetString(0, value)
            Return record
        End Function
    Dim userNameRecords As IEnumerable(Of SqlDataRecord) = userNames.Select(setRecord)
    Dim roleNameRecords As IEnumerable(Of SqlDataRecord) = rolenames.Select(setRecord)
    With sqldb
        .AddInParameter(command, "userNames", SqlDbType.Structured, userNameRecords)
        .AddInParameter(command, "roleNames", SqlDbType.Structured, roleNameRecords)
        .AddInParameter(command, "applicationId", DbType.Int32, applicationId)
        .AddInParameter(command, "currentUserName", DbType.String, GetUpdatingUserName)
        .ExecuteNonQuery(command)
    End With
End Sub

Ответ 7

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

В VB.NET

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

В С#

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;
    }
}