Frage

Es sieht so aus, als würde man den Aufzähler einer Liste an eine Funktion "Byval" übergeben, ist ganz anders als "Byref". Im Wesentlichen ändert das regelmäßige "Byval" -Passer nicht den "Enumerator.Current Value" des Anrufers, selbst wenn die Funktion den Enumerator voranschreitet. Ich habe mich gefragt, ob jemand weiß, warum dies der Fall ist. Ist ein Enumerator ein Primitiv wie eine Ganzzahl ohne Objektreferenz, und daher wird sich im Anrufer nicht reflektiert?

Hier ist der Beispielcode:

Diese Funktion ist byval und steckt in einer unendlichen Schleife stecken und spuckt "1" -Beachboxen aus, da der "aktuelle" des Enumerators nie nach 5 vorbringt:

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

Dies hingegen funktioniert genauso wie man erwarten würde:

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

Der Unterschied zwischen den beiden Funktionen besteht nur darin, ob die ListFirstitem__ -Funktion einen Byval oder einen ByRef -Enumerator akzeptiert.

War es hilfreich?

Lösung

Der Grund, warum Sie dieses Verhalten sehen, ist das List(Of T).Enumerator ist ein Struct und nicht a Class Wie allgemein erwartet. Wenn Sie also den Enumerator übergeben, passieren Sie eine Kopie davon und daher wird nur diese Kopie aktualisiert, wenn Sie anrufen MoveNext

Andere Tipps

Die Verwendung des angegebenen Beispielcodes würde nicht mit der Option strikt kompilieren. Behebung, die den von Ihnen angezeigten Unterschied beheben kann.

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top