Reputation: 12396
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
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
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
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
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