Raúl Roa
Raúl Roa

Reputation: 12396

C# to VB .NET yield return conversion

What's the translation of this snippet in VB .NET?

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

Upvotes: 3

Views: 2381

Answers (4)

bbqchickenrobot
bbqchickenrobot

Reputation: 3709

This question is old, but for people coming here from Google there is good news - new releases of VB.NET have support for the c# yield return operator (I believe this isn VS.NET 2010/2012 w/ .net 4.0)... Here is the converted sample:

<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

There is no need to change static to shared as VB.NET extension methods must be defined in Modules which are automatically 'shared' or static.

Upvotes: 5

womp
womp

Reputation: 116987

Unfortunately, as far as I know, VB.net has no equivalent to the yield keyword. In order to implement the yield functionality, you'll have to look at doing some fancy moves with IEnumerable<T>... you can check out this article for a good walkthrough.

If you're just looking for the syntax for extension methods, here's what it would look like:

<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)

Upvotes: 3

Marc Gravell
Marc Gravell

Reputation: 1063704

The problem there is that VB does not support iterator blocks. Can you not just use the existing Enumerable.Where method from VB?

The other lazy way of doing it in VB would be to consume and filter the entire sequence first - and just return the resulting array/list, but that wouldn't have the deferred execution that C# iterator blocks offer. Which is a pain; I often use iterator blocks with long (i.e. essentially infinite) sequences.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1502696

The problem here isn't converting an extension method - it's converting an iterator block (the method uses yield return. VB doesn't have any equivalent language construct - you'd have to create your own implementation of IEnumerable<T> which did the filtering, then return an instance of the class from the extension method.

That's exactly what the C# compiler does, but it's hidden behind the scenes.

One point to note, which might not be obvious otherwise: IEnumerator<T> implements IDisposable, and a foreach loop disposes of the iterator at the end. This can be very important - so if you do create your own implementation of this (and I'd recommend that you don't, frankly) you'll need to call Dispose on the iterator returned from source.GetEnumerator() in your own Dispose method.

Upvotes: 5

Related Questions