将列表的枚举器传递给函数

时间:2011-12-02 17:16:59

标签: .net vb.net enumerator

将列表的枚举器传递给函数“byval”与将其传递给“byref”完全不同。基本上,常规的“byval”传递不会改变调用者的“enumerator.Current值”,即使该函数使枚举器前进。我想知道是否有人知道为什么会这样?枚举器是一个整数的原语,没有对象引用,因此对它的更改不会反映在调用者中吗?

以下是示例代码:

这个函数是byval,并且陷入无限循环,吐出“1”消息框,因为枚举器的“当前”从未超过5:

Public Sub listItemsUsingByValFunction()
    Dim list As New List(Of Integer)(New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})

    Dim enumerator = list.GetEnumerator()
    enumerator.MoveNext()
    While enumerator.Current <= 5
        listFirstItemByVal(enumerator)
    End While
End Sub
Private Sub listFirstItemByVal(ByVal enumerator As List(Of Integer).Enumerator)
    MsgBox(enumerator.Current)
    enumerator.MoveNext()
End Sub

另一方面,这可以像人们期望的那样工作:

Public Sub listItemsUsingByRefFunction()
    Dim list As New List(Of Integer)(New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})

    Dim enumerator = list.GetEnumerator()
    enumerator.MoveNext()
    While enumerator.Current <= 5
        listFirstItemByRef(enumerator)
    End While
End Sub
Private Sub listFirstItemByRef(ByRef enumerator As List(Of Integer).Enumerator)
    MsgBox(enumerator.Current)
    enumerator.MoveNext()
End Sub

这两个函数之间的区别仅在于listFirstItem__函数是接受byval还是byref枚举器。

2 个答案:

答案 0 :(得分:8)

您看到此行为的原因是List(Of T).EnumeratorStruct而不是Class,这是通常所期望的。因此,当您传递枚举器时,您传递了它的副本,因此当您致电MoveNext时,只有该副本会更新

答案 1 :(得分:0)

使用提供的示例代码无法使用Option Strict On进行编译。修复可以解决你看到的差异。

Public Sub listItemsUsingByValFunction()
    Dim list As New List(Of Integer)(New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})

    Dim enumerator As IEnumerator(Of Integer) = list.GetEnumerator()
    enumerator.MoveNext()
    Debug.WriteLine("S " & enumerator.Current)
    Stop
    Do
        Debug.WriteLine("W " & enumerator.Current)
        If Not listFirstItemByVal(enumerator) Then Exit Do
    Loop
End Sub

Private Function listFirstItemByVal(ByVal enumerator As IEnumerator(Of Integer)) As Boolean
    Debug.WriteLine("F " & enumerator.Current)
    Return enumerator.MoveNext()
End Function

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    listItemsUsingByValFunction()
End Sub