2009-05-17 11 views
9

Mögliche Duplizieren:
Yield In VB.NETKann ich die Rendite für IEnumerable-Funktionen in VB.NET implementieren?

In C#, wenn eine Funktion zu schreiben, die eine IEnumerble<> zurückgibt, können Sie yield return verwenden, um ein einzelnes Element der Aufzählung zurückzukehren und yield break; kein verbleib zu bedeuten Artikel. Was ist die VB.NET-Syntax für die gleiche Sache?

Ein Beispiel aus dem NerdDinner Code:

public IEnumerable<RuleViolation> GetRuleViolations() { 

    if (String.IsNullOrEmpty(Title)) 
     yield return new RuleViolation("Title required","Title"); 

    if (String.IsNullOrEmpty(Description)) 
     yield return new RuleViolation("Description required","Description"); 

    if (String.IsNullOrEmpty(HostedBy)) 
     yield return new RuleViolation("HostedBy required", "HostedBy"); 

    if (String.IsNullOrEmpty(Address)) 
     yield return new RuleViolation("Address required", "Address"); 

    if (String.IsNullOrEmpty(Country)) 
     yield return new RuleViolation("Country required", "Country"); 

    if (String.IsNullOrEmpty(ContactPhone)) 
     yield return new RuleViolation("Phone# required", "ContactPhone"); 

    if (!PhoneValidator.IsValidNumber(ContactPhone, Country)) 
     yield return new RuleViolation("Phone# does not match country", "ContactPhone"); 

    yield break; 
} 

Diese convert C# to VB.NET tool gibt ein Fehler "YieldStatement nicht unterstützt wird". Jedoch

+0

Beachten Sie, dass das Nachgeben nicht zurückkehrt, zumindest nicht in dem Sinne, dass die meisten Menschen die Rückkehr bedeuten (die Art und Weise, wie es unter der Haube ausgeführt wird). Außerdem brauchen Sie dort keine Rendite.Außerdem sollten Sie darüber nachdenken, diesen Code dahingehend zu transformieren, dass eine Enumeration von RuleViolation-Objekten in eine Enumeration von Func Delegaten resultiert. – yfeldblum

+0

Die Verwendung von Yield erinnert mich an die Piping-Funktion, in der der Calling-Code mit der Iteration beginnen kann, bevor * die Funktion, die das Imenumerable zurückgibt, beendet ist. Sehr cool! –

+2

Das ist ein schreckliches Beispiel, weil Sie offensichtlich nichts für so etwas brauchen: Was ist der Vorteil, die Regelverstöße träge zu bestimmen? Stopf sie alle in eine Liste und sei damit fertig. Das ist nicht zu sagen, YEILD ist nicht nützlich, aber das ist nur ein schlechtes Beispiel – piers7

Antwort

0

Keine Ausbeute Rückkehr in VB.NET :( einfach eine Liste erstellen und es zurück.

2

Siehe meine Antworten hier:

Fassen wir zusammen:
VB.Net nicht Ausbeute hat, aber C# implementiert Ausbeute von Ihrem Code zu einer Zustandsmaschine Umwandlung hinter diesen Szenen. Das Schlüsselwort Static von VB.Net ermöglicht es Ihnen auch, den Status innerhalb einer Funktion zu speichern. In der Theorie sollten Sie also in der Lage sein, eine Klasse zu implementieren, mit der Sie ähnlichen Code schreiben können, wenn Sie als Static Mitglied einer Methode verwendet werden.

0

Hinter den Kulissen erstellt der Compiler eine Enumerator-Klasse, um die Arbeit zu erledigen. Da VB.NET dieses Muster nicht implementiert, müssen Sie Ihre eigene Implementierung von IEnumerator erstellen (Of T)

0

Unten gibt Ausgang: 2, 4, 8, 16, 32

In VB,

Public Shared Function setofNumbers() As Integer() 

    Dim counter As Integer = 0 
    Dim results As New List(Of Integer) 
    Dim result As Integer = 1 
    While counter < 5 
     result = result * 2 
     results.Add(result) 
     counter += 1 
    End While 
    Return results.ToArray() 
End Function 

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
    For Each i As Integer In setofNumbers() 
     MessageBox.Show(i) 
    Next 
End Sub 

in C#

private void Form1_Load(object sender, EventArgs e) 
    { 
     foreach (int i in setofNumbers()) 
     { 
      MessageBox.Show(i.ToString()); 
     } 
    } 

    public static IEnumerable<int> setofNumbers() 
    { 
     int counter=0; 
     //List<int> results = new List<int>(); 
     int result=1; 
     while (counter < 5) 
     { 
      result = result * 2; 
      counter += 1; 
      yield return result; 
     } 
    } 
+2

Ja, für dieses einfache Beispiel würde das funktionieren. Es gibt andere bessere Beispiele für Iteratoren, bei denen Sie nicht die gesamte Liste innerhalb eines einzelnen Funktionsaufrufs erstellen möchten oder können. Ihr C# -Code berechnet jeden Wert nur so, wie Sie ihn innerhalb der 'foreach'-Schleife verwenden. Der VB-Code berechnet alle Werte beim Aufruf der Funktion 'setOfNumbers'. Das ist ein wesentlicher Unterschied. – CoderDennis