2009-07-17 11 views
3

Was ist die Übersetzung dieses Snippets in VB .NET?C# zu VB .NET Rendite-Konvertierung

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

Antwort

5

Das Problem hier ist kein Verlängerungsumwandlungsverfahren - es eine Iteratorblock Converting (das Verfahren yield return. VB hat kein gleichwertiges Sprachkonstrukt - Sie müssten Ihre eigene Implementierung von IEnumerable<T> erstellen, die die Filterung durchgeführt hat, und dann eine Instanz der Klasse von der Erweiterungsmethode zurückgeben.

Genau das ist die C# Compiler tut, aber es ist hinter den Kulissen versteckt.

Ein Punkt zu beachten, der sonst nicht offensichtlich sein könnte: IEnumerator<T> implementiert IDisposable, und eine foreach Schleife verfügt über den Iterator am Ende. Dies kann sehr wichtig sein - also wenn Sie tun erstellen Sie Ihre eigene Implementierung von diesem (und ich würde empfehlen, dass Sie nicht, ehrlich gesagt) müssen Sie Dispose auf den Iterator von source.GetEnumerator() in Ihrer eigenen Dispose Methode aufrufen .

3

Leider, soweit ich weiß, hat VB.net keine Entsprechung zu dem yield Schlüsselwort. Um die yield Funktionalität zu implementieren, müssen Sie einige ausgefallene Moves mit IEnumerable<T> betrachten ... Sie können this article für eine gute Komplettlösung auschecken.

Wenn Sie gerade für die Syntax für Erweiterungsmethoden suchen, ist hier, wie es aussehen würde:

<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

Das Problem dort ist, dass VB Iterator Blöcke nicht unterstützt. Können Sie nicht einfach die vorhandene Enumerable.Where Methode von VB verwenden? Der andere faule Weg, es in VB zu tun wäre, die gesamte Sequenz zu konsumieren und zu filtern - - und nur das resultierende Array/Liste zurückgeben, aber das hätte nicht die verzögerte Ausführung, die C# Iteratorblöcke bieten. Was ist ein Schmerz; Ich benutze häufig Iteratorblöcke mit langen (d. H. Im Wesentlichen unendlichen) Sequenzen.

6

Diese Frage ist alt, aber für Leute, die von Google hierher kommen, gibt es gute Nachrichten - neue Versionen von VB.NET unterstützen den C# yield return operator (ich glaube das ist VS.NET 2010/2012 w/.net 4.0) ... Hier ist das konvertierte Beispiel:

<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 

Es besteht keine Notwendigkeit statisch geteilt zu ändern, wie VB.NET Erweiterungsmethoden müssen in Module definiert werden, die automatisch ‚geteilt‘ werden oder statisch.

+1

Von George arbeitet 'Yield' in vb.net 10.0 (.Net 4.0)! – toddmo