(ASP NET) ASP (2012)

Yield/Iterator/IEnumerable - і ці люди забороняли нам багато років колупатися у носі?

Увесь пафос гарного коду багато-багато років будувався на лінійності коду, на відсутності GOTO та стрибків між фрагментами коду. Дозволеним вважалися лише IF та цикли. Ось подивиться, будь ласка на цю істерію щодо GOTO.

А тепер подивиться, будь ласка, як працює оператор нової версії бейсіку YIELD:


   1:  Module Module1
   2:      
   3:      Sub Main()
   4:          
   5:          ' Output: A1,3,A2,5,A3,8,A4
   6:          For Each number As Integer In SomeNumbers()
   7:              Debug.Print(number)
   8:          Next
   9:   
  10:          ' Output: B1,2,B2,B1,4,B2,B1,8,B2,B1,16,B2,B1,32,B2,B1,64,B2,B1,128,B2,B1,256,B2
  11:          For Each number In Power(2, 8)
  12:              Debug.Print(number)
  13:          Next
  14:   
  15:          ' Output: C1,Sun,C2,C1,Mon,C2,C1,Tue,C2,C1,Wed,C2,C1,Thu,C2,C1,Fri,C2,C1,Sat,C2
  16:          Dim days As New DaysOfTheWeek()
  17:          For Each day As String In days
  18:              Debug.Print(day)
  19:          Next
  20:   
  21:          ' Output: D1,1,D2,2,D3
  22:          Dim iterateSequence = Iterator Function() _
  23:                        As IEnumerable(Of Integer)
  24:                                    Debug.Print("D1")
  25:                                    Yield 1
  26:                                    Debug.Print("D2")
  27:                                    Yield 2
  28:                                    Debug.Print("D3")
  29:                                End Function
  30:   
  31:          For Each number As Integer In iterateSequence()
  32:              Debug.Print(number)
  33:          Next
  34:   
  35:   
  36:          ' Output: E1,E2,E7,E3,E4,5,E5,E4,6,E5,E4,7,E5,E4,8,E5,E4,9,E5,E4,10,E5,E6
  37:          For Each number As Integer In GetSequence(5, 10)
  38:              Debug.Print(number)
  39:          Next
  40:  
  41:          ' Output: F2,F1,F7,Tadpole  400,F3,F1,F7,Pinwheel  25,F4,F1,F7,Milky Way  0,F5,F1,F7,Andromeda  3,F6
  42:          Dim theGalaxies As New Galaxies
  43:          For Each theGalaxy In theGalaxies.NextGalaxy
  44:              Debug.Print("F7")
  45:              With theGalaxy
  46:                  Debug.Print(.Name & "  " & .MegaLightYears)
  47:              End With
  48:          Next
  49:          Console.ReadKey()
  50:   
  51:      End Sub
  52:   
  53:      Private Iterator Function SomeNumbers() As System.Collections.IEnumerable
  54:          Debug.Print("A1")
  55:          Yield 3
  56:          Debug.Print("A2")
  57:          Yield 5
  58:          Debug.Print("A3")
  59:          Yield 8
  60:          Debug.Print("A4")
  61:      End Function
  62:   
  63:      Private Iterator Function Power(ByVal base As Integer, ByVal highExponent As Integer) _
  64:          As System.Collections.Generic.IEnumerable(Of Integer)
  65:   
  66:          Dim result = 1
  67:          For counter = 1 To highExponent
  68:              result = result * base
  69:              Debug.Print("B1")
  70:              Yield result
  71:              Debug.Print("B2")
  72:          Next
  73:      End Function
  74:   
  75:      Private Function GetSequence(ByVal low As Integer, ByVal high As Integer) As IEnumerable
  76:          Debug.Print("E1")
  77:          If low < 1 Then
  78:              Throw New ArgumentException("E!")
  79:          End If
  80:          Debug.Print("E2")
  81:          '  
  82:          Dim iterateSequence = Iterator Function() As IEnumerable
  83:                                    Debug.Print("E3")
  84:                                    For index = low To high
  85:                                        Debug.Print("E4")
  86:                                        Yield index
  87:                                        Debug.Print("E5")
  88:                                    Next
  89:                                    Debug.Print("E6")
  90:                                End Function
  91:          Debug.Print("E7")
  92:          Return iterateSequence()
  93:      End Function
  94:   
  95:   
  96:  End Module
  97:   
  98:   
  99:  Public Class DaysOfTheWeek
 100:      Implements IEnumerable
 101:   
 102:      Public days = New String() {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}
 103:   
 104:      Public Iterator Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
 105:          
 106:          For i As Integer = 0 To days.Length - 1
 107:              Debug.Print("C1")
 108:              Yield days(i)
 109:              Debug.Print("C2")
 110:          Next
 111:      End Function
 112:  End Class
 113:   
 114:  Public Class Galaxies
 115:      Public ReadOnly Iterator Property NextGalaxy _
 116:          As System.Collections.Generic.IEnumerable(Of Galaxy)
 117:          Get
 118:              Debug.Print("F2")
 119:              Yield New Galaxy With {.Name = "Tadpole", .MegaLightYears = 400}
 120:              Debug.Print("F3")
 121:              Yield New Galaxy With {.Name = "Pinwheel", .MegaLightYears = 25}
 122:              Debug.Print("F4")
 123:              Yield New Galaxy With {.Name = "Milky Way", .MegaLightYears = 0}
 124:              Debug.Print("F5")
 125:              Yield New Galaxy With {.Name = "Andromeda", .MegaLightYears = 3}
 126:              Debug.Print("F6")
 127:          End Get
 128:      End Property
 129:  End Class
 130:   
 131:  Public Class Galaxy
 132:      Public Sub New()
 133:          Debug.Print("F1")
 134:      End Sub
 135:      Public Property Name As String
 136:      Public Property MegaLightYears As Integer
 137:  End Class

Сподіваюсь, друзі - ви зрозуміли, що трапиться в коді вище. Які б слова не казали, які в команди ми не писали, але виконуються зовсім різні клаптики коду в такому порядку, який ще потрібно зрозуміти. Будь-яка крихітна помилка приведе до зовсім іншому порядку виконання всіх клаптиків коду. Про яке тут GOTO взагалі мова може йти? Код, побудований на основі GOTO - порівняно з YIELD - це образчик лінійності та передбачуваності порядку виконання коду.



Next example Serialize Table to CSV with Iterator and Yeld.



Comments ( )
<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17>  <18>  <19>  <20>  <21
Link to this page: http://www.vb-net.com/Yield/index.htm
<SITEMAP>  <MVC>  <ASP>  <NET>  <DATA>  <KIOSK>  <FLEX>  <SQL>  <NOTES>  <LINUX>  <MONO>  <FREEWARE>  <DOCS>  <ENG>  <CHAT ME>  <ABOUT ME>  < THANKS ME>