5

リストの列挙子を関数「byval」に渡すことは、「byref」に渡すこととはまったく異なるように見えます。基本的に、通常の「byval」パスは、関数が列挙子を進めても、呼び出し元の「enumerator.Currentvalue」を変更しません。なぜそうなのか誰かが知っているのだろうか?列挙子は、オブジェクト参照のない整数のようなプリミティブであり、したがって、列挙子への変更は呼び出し元に反映されませんか?

サンプルコードは次のとおりです。

この関数は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

2つの関数の違いは、listFirstItem__関数がbyvalまたはbyref列挙子を受け入れるかどうかだけです。

4

2 に答える 2

8

この動作が見られる理由List(Of T).Enumeratorは、一般的に予想されているようにではStructなく、であるためです。Classしたがって、列挙子を渡すと、そのコピーが渡されるため、呼び出したときにそのコピーのみが更新されます。MoveNext

于 2011-12-02T17:19:28.683 に答える
0

提供されているサンプルコードを使用しても、OptionStrictOnを使用してコンパイルすることはできません。あなたが見る違いを修正するかもしれない修正。

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
于 2011-12-02T18:42:21.610 に答える