2009-07-17 3 views
3

Что такое перевод этого фрагмента в VB .NET?C# to VB .NET return return conversion

public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source, 
Func<TSource, Boolean> predicate) 
{ 
    foreach (TSource element in source) 
    { 
    if (predicate(element)) 
    yield return element; 
    } 
} 

ответ

5

Проблемы здесь не преобразование методы расширения - это преобразование блока итератора (метод использует yield return VB не имеет эквивалентную конструкцию языка. - вы должны были бы создать свою собственную реализацию IEnumerable<T>, который сделал фильтрацию, а затем возвращает экземпляр класса из метода расширения

Это именно то, что C#. компилятор, но он скрыт за кулисами.

Следует отметить, что это может быть не очевиден иначе: IEnumerator<T> реализует IDisposable, а петля foreach имеет итератор в конце. Это может быть очень важно - так что если вы do создайте свою собственную реализацию (и я бы рекомендовал, чтобы вы этого не сделали, если честно), вам нужно будет позвонить Dispose на итераторе, возвращенном с source.GetEnumerator() в вашем собственном Dispose методе ,

3

К сожалению, насколько я знаю, VB.net не имеют аналогов в yield ключевое слово. Чтобы реализовать функциональность yield, вам нужно будет посмотреть, как сделать некоторые причудливые ходы с помощью IEnumerable<T> ... вы можете проверить this article за хорошее прохождение игры.

Если вы просто ищете синтаксис для методов расширения, вот что это будет выглядеть так:

<System.Runtime.CompilerServices.Extension> _ 
Public Shared Function Where(Of TSource) (_ 
       ByVal source As IEnumerable(Of TSource), _ 
       ByVal predicate As Func(Of TSource, [Boolean])) _ 
     As IEnumerable(Of TSource) 
1

Проблема в том, что VB не поддерживает блоки итераторов. Не можете ли вы использовать существующий метод Enumerable.Where от VB?

Другой ленивый способ сделать это в VB будет потреблять и фильтровать всю последовательность первого - и просто возвращает результирующий массив/список, но это не будет иметь отложенное выполнение, что C# итераторы блоки предлагают. Это боль; Я часто использую итераторные блоки с длинными (то есть практически бесконечными) последовательностями.

6

Этот вопрос старый, но для людей, приезжающих сюда из Google, есть хорошие новости - новые версии VB.NET поддерживают оператор возврата C# yield (я считаю, что это VS.NET 2010/2012 w/.net 4,0) ... Вот преобразованный образец:

<System.Runtime.CompilerServices.Extension> _ 
Public Iterator Function Where(Of TSource)(source As IEnumerable(Of TSource), predicate As Func(Of TSource, [Boolean])) As IEnumerable(Of TSource) 
    '' non-lambda version of the method body 
    'For Each element As TSource In source 
    ' If predicate(element) Then 
    '  Yield element 
    ' End If 
    'Next 
    For Each element As TSource In From item In source Where predicate(item) 
     Yield element 
    Next 
End Function 

Там нет необходимости менять статическую совместно, как методы расширения VB.NET должны быть определены в модулях, которые автоматически «совместно» или статические.

+1

Автор George, 'Yield' работает в vb.net 10.0 (.Net 4.0)! – toddmo