否,您不能在設計時訪問自動生成的迭代器。
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
相關參考資料:
對於你的例子,你可以使用'Enumerable.Except'方法。 – 2015-02-17 20:30:18
是的,但你告訴我可以在返回的集合上使用'Enumerable.Except',但是函數本身應該避免重複,而不是在集合構建完成後手動執行。無論如何,這是一個例子,可能有更多的原因,爲什麼我想訪問函數內正在建立的集合。感謝您的評論 – ElektroStudios 2015-02-17 20:31:28
我不知道我理解你的問題。什麼是'THE_ITERATOR_COLLECTION'?如果這是使用'Contains'方法的一些集合,那麼你的代碼應該與打字錯誤分開(你在循環中使用任何值而不是值)。否則我不明白你的意思。什麼是問題。什麼不行? – 2015-02-17 20:35:15