2015-02-17 63 views
0

如果我沒有弄錯,Iterator函數可以更快地構建一個集合,因爲它記住了添加最後一個項目的索引。迭代器函數缺失理解概念

現在,有沒有辦法訪問正在構建的集合?

例如,讓我們說,我需要確定集合中是否包含收益率前一個元素的新元素,像這樣(一個極壞的榜樣):

Public Iterator Function MyFunc(Byval param1 As whatever) As IEnumerable(Of whatever) 

    For value As Integer = 0 to whatever 

     If Not THE_ITERATOR_COLLECTION.Contains(whatever) 
      Yield value 
     End If 

    End For 

End Function 

這可能嗎?

+0

對於你的例子,你可以使用'Enumerable.Except'方法。 – 2015-02-17 20:30:18

+0

是的,但你告訴我可以在返回的集合上使用'Enumerable.Except',但是函數本身應該避免重複,而不是在集合構建完成後手動執行。無論如何,這是一個例子,可能有更多的原因,爲什麼我想訪問函數內正在建立的集合。感謝您的評論 – ElektroStudios 2015-02-17 20:31:28

+0

我不知道我理解你的問題。什麼是'THE_ITERATOR_COLLECTION'?如果這是使用'Contains'方法的一些集合,那麼你的代碼應該與打字錯誤分開(你在循環中使用任何值而不是值)。否則我不明白你的意思。什麼是問題。什麼不行? – 2015-02-17 20:35:15

回答

1

,您不能在設計時訪問自動生成的迭代器。

Iterator關鍵字提供了一種快速簡便的方法來創建迭代器,而無需實際創建迭代器。它由編譯器創建(基於迭代器函數/屬性),因此在設計時不可用。您必須創建自定義迭代器或重新考慮設計。

看看這個簡單的迭代器函數。

Public Iterator Function Foo() As IEnumerable(Of Char) 
    Yield "H"c 
    Yield "E"c 
    Yield "L"c 
    Yield "L"c 
    Yield "O"c 
End Function 

上述函數被編譯成如下所示的函數。自動生成的迭代器的類型被命名爲VB $ StateMachine_0_Foo

Public Function Foo() As IEnumerable(Of Char) 
    Dim $sm As New VB$StateMachine_0_Foo 
    $sm.$VB$Me = Me 
    $sm.$State = -2 
    Return $sm 
End Function 

迭代器的內部工作沒有什麼特別之處。它和任何其他精心製作的迭代器的工作方式相同。

<CompilerGenerated> _ 
Private NotInheritable Class VB$StateMachine_0_Foo 
    Implements IDisposable, IEnumerator, IEnumerator(Of Char), IEnumerable, IEnumerable(Of Char) 

    <DebuggerNonUserCode> _ 
    Private Overrides Function GetEnumerator() As IEnumerator(Of Char) Implements IEnumerable(Of Char).GetEnumerator 
     If ((Thread.CurrentThread.ManagedThreadId = Me.$InitialThreadId) AndAlso (Me.$State = -2)) Then 
      Me.$State = -1 
      Return Me 
     End If 
     Dim foo As New VB$StateMachine_0_Foo 
     foo.$VB$Me = Me.$VB$Me 
     Return foo 
    End Function 

    <DebuggerNonUserCode> _ 
    Private Overrides Function GetEnumerator0() As IEnumerator Implements IEnumerable.GetEnumerator 
     Return Me.GetEnumerator 
    End Function 

    <CompilerGenerated> _ 
    Friend Overrides Function MoveNext() As Boolean Implements IEnumerator.MoveNext 
     Dim VB$doFinallyBodies As Boolean = True 
     Try 
      Select Case Me.$State 
       Case 0 
        If Not Me.$Disposing Then 
         GoTo Label_0066 
        End If 
        Return False 
       Case 1 
        If Not Me.$Disposing Then 
         GoTo Label_0099 
        End If 
        Return False 
       Case 2 
        If Not Me.$Disposing Then 
         GoTo Label_00CC 
        End If 
        Return False 
       Case 3 
        If Not Me.$Disposing Then 
         GoTo Label_00F9 
        End If 
        Return False 
       Case 4 
        If Not Me.$Disposing Then 
         GoTo Label_0126 
        End If 
        Return False 
       Case 5 
        Exit Select 
       Case Else 
        If Not Me.$Disposing Then 
         GoTo Label_0039 
        End If 
        Exit Select 
      End Select 
      Return False 
Label_0039: 
      Me.$Current = "H"c 
      Me.$State = 0 
      VB$ doFinallyBodies = False 
      Return True 
Label_0066: 
      Me.$State = -1 
      Me.$Current = "E"c 
      Me.$State = 1 
      VB$ doFinallyBodies = False 
      Return True 
Label_0099: 
      Me.$State = -1 
      Me.$Current = "L"c 
      Me.$State = 2 
      VB$ doFinallyBodies = False 
      Return True 
Label_00CC: 
      Me.$State = -1 
      Me.$Current = "L"c 
      Me.$State = 3 
      VB$ doFinallyBodies = False 
      Return True 
Label_00F9: 
      Me.$State = -1 
      Me.$Current = "O"c 
      Me.$State = 4 
      VB$ doFinallyBodies = False 
      Return True 
Label_0126: 
      Me.$State = -1 
     Catch exception1 As Exception 
      ProjectData.SetProjectError(exception1) 
      Dim $ex As Exception = exception1 
      Me.$State = 5 
      Throw 
      ProjectData.ClearProjectError() 
     End Try 
     Me.$State = 5 
     Return False 
    End Function 

    <DebuggerNonUserCode> _ 
    Private Overrides Sub System.Collections.IEnumerator.Reset() Implements IEnumerator.Reset 
     Throw New NotSupportedException 
    End Sub 

    <DebuggerNonUserCode> _ 
    Private Overrides Sub System.IDisposable.Dispose() Implements IDisposable.Dispose 
     Me.$Disposing = True 
     Me.MoveNext() 
     Me.$State = 5 
    End Sub 

    Private Overrides ReadOnly Property System.Collections.Generic.IEnumerator(Of Char).Current As Char 
     <DebuggerNonUserCode> _ 
     Get 
      Return Me.$Current 
     End Get 
    End Property 

    Private Overrides ReadOnly Property System.Collections.IEnumerator.Current As Object 
     <DebuggerNonUserCode> _ 
     Get 
      Return Me.$Current 
     End Get 
    End Property 

    Friend $Current As Char 
    Friend $Disposing As Boolean 
    Friend $InitialThreadId As Integer = Thread.CurrentThread.ManagedThreadId 
    Friend $State As Integer = -1 
    Friend $VB$Me As Form1 

End Class 

相關參考資料: