tags:

views:

291

answers:

3

Hello,

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;
  }
}
+2  A: 

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)
womp
+4  A: 

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.

Jon Skeet
+1  A: 

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.

Marc Gravell