Выход в VB.NET

C # имеет ключевое слово, называемое yield . VB.NET не хватает этого ключевого слова. Как программисты на Visual Basic воспользовались отсутствием этого ключевого слова? Они реализуют свой class iteratorов? Или они пытаются и кодируют, чтобы избежать необходимости iteratorа?

Ключевое слово yield заставляет компилятор делать некоторую кодировку за кулисами. Хорошим примером этого является реализация iteratorов в C # и его последствиях (часть 1) .

Примечание. Этот ответ старый. С тех пор блоки Iterator были добавлены в VB.NET

C # переводит ключевое слово yield в конечный автомат во время компиляции. У VB.NET нет ключевого слова yield, но у него есть свой собственный механизм безопасного встраивания состояния в функцию, которая нелегко доступна на C #.

static ключевое слово C # обычно переводится на Visual Basic с использованием ключевого слова Shared , но есть два места, где вещи запутываются. Один из них заключается в том, что статический class C # действительно является модулем в Visual Basic, а не для classа Shared (вы думаете, что они позволят вам кодировать его в любом случае в Visual Basic, но noooo). Другим является то, что VB.NET имеет собственное ключевое слово Static . Тем не менее, Static имеет другое значение в VB.NET.

Вы используете ключевое слово Static в VB.NET, чтобы объявить переменную внутри функции, и когда вы выполняете переменную, она сохраняет свое состояние при вызове функций. Это отличается от простого объявления частного статического члена classа в C #, поскольку гарантированный статический член функции в VB.NET также может быть streamобезопасным, поскольку компилятор переводит его на использование classа Monitor во время компиляции.

Так зачем писать все это здесь? Ну, должно быть возможно создать повторно используемый универсальный class Iterator (или Iterator(Of T) в VB.NET). В этом classе вы бы использовали конечный автомат, используемый C #, с методами Yield() и Break() которые соответствуют ключевым словам C #. Затем вы можете использовать статический экземпляр (в смысле VB.NET) в функции, чтобы он мог в конечном итоге выполнить почти ту же работу, что и yield C # в примерно таком же количестве кода (отбрасывая само реализацию classа, поскольку это было бы бесконечно повторное использование).

Я не заботился о Доходе, чтобы попытаться сам, но это должно быть выполнимо. Тем не менее, это также далеко не тривиально, так как член команды C # Эрик Липперт называет это « самым сложным преобразованием в компиляторе ».

Я также поверил, так как я написал первый проект этого года назад, что это действительно не реально, до тех пор, пока не появится Visual Studio 2010, так как это потребует отправки нескольких lambdas в class Iterator и, чтобы быть действительно Практически нам нужна поддержка .NET 4 для многострочных lambdas.

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

Информацию об использовании см. В разделе Итераторы в Visual Basic .

И теперь он включен в коробку с Visual Studio 2012!

Там хорошая статья « Использование iteratorов» в VB. Теперь Билл МакКарти в журнале Visual Studio Magazine по эмуляции yield в VB.NET. В качестве альтернативы дождитесь следующей версии Visual Basic.

Я лично просто пишу свой собственный class iteratorа, который наследуется от IEnumerator (Of T). Это займет некоторое время, чтобы понять это правильно, но я думаю, что в конечном итоге лучше написать его, а затем попытаться избежать этого. Другой метод, который я сделал, это написать рекурсивный метод, который возвращает IEnumerable (Of T) и просто возвращает List (Of T) и использует .AddRange.

К счастью, теперь у нас есть Yield
вот пример из моего проекта + реализация интерфейса с функцией System.Collections.Generic.IEnumerable(T) :

 Public Class Status Implements IStatus Private _statusChangeDate As DateTime Public Property statusChangeDate As DateTime Implements IStatus.statusChangeDate Get Return _statusChangeDate End Get Set(value As Date) _statusChangeDate = value End Set End Property Private _statusId As Integer Public Property statusId As Integer Implements IStatus.statusId Get Return _statusId End Get Set(value As Integer) _statusId = value End Set End Property Private _statusName As String Public Property statusName As String Implements IStatus.statusName Get Return _statusName End Get Set(value As String) _statusName = value End Set End Property Public Iterator Function GetEnumerator() As IEnumerable(Of Object) Implements IStatus.GetEnumerator Yield Convert.ToDateTime(statusChangeDate) Yield Convert.ToInt32(statusId) Yield statusName.ToString() End Function End Class Public Interface IStatus Property statusChangeDate As DateTime Property statusId As Integer Property statusName As String Function GetEnumerator() As System.Collections.Generic.IEnumerable(Of Object) End Interface 

Вот как я извлекаю все свойства извне:

 For Each itm As SLA.IStatus In outputlist For Each it As Object In itm.GetEnumerator() Debug.Write(it & " ") Next Debug.WriteLine("") Next 

Надеюсь, это будет в прошлом с предстоящей версией VB. Поскольку iteratorы на самом деле приобретают большое значение с новыми парадигмами (особенно LINQ в сочетании с ленивой оценкой), это имеет довольно высокий приоритет, насколько я знаю из блога Пола Вика. Опять же, Пол больше не является главой команды VB, и я еще не успел посмотреть переговоры по PCD.

Тем не менее, если вам интересно, они связаны в блоге Павла .

Приведенный ниже код дает результат

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 

В C #

 private void Form1_Load(object sender, EventArgs e) { foreach (int i in setofNumbers()) { MessageBox.Show(i.ToString()); } } public static IEnumerable setofNumbers() { int counter=0; int result=1; while (counter < 5) { result = result * 2; counter += 1; yield return result; } } 

VB.NET имеет ключевое слово Iterator https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/modifiers/iterator

Поскольку Visual Studio 2012 кажется

  • Поиск всех пространств имен в сборке с использованием Reflection (DotNET)
  • Выбор того IP-адреса, который используется HTTP-запросом при наличии нескольких IP-адресов (.NET)
  • Можно ли записать на консоль цвет в .NET?
  • VB.NET - IIF (,,) - оцениваются обе «стороны». В каких ситуациях я должен следить?
  • VB.NET. Какова цель classа или модуля?
  • Передача параметра в запрос для базы данных Access
  • Вариант Strict On и .NET для программистов VB6
  • LinqToSql объявляет и внедряет лучшую практику DataContext?
  • Свойство привязки для управления в Winforms
  • «Тени» против «Переопределения» в VB.NET
  • Управление объемом приложения: по идентификатору процесса
  • Давайте будем гением компьютера.