En passant la recenseur d'une liste à une fonction
-
27-10-2019 - |
Question
On dirait que le passage de recenseur d'une liste à une fonction « byval » est tout à fait différent de la transmettre « byref ». Essentiellement, régulière « byval » qui passe ne changera pas « la valeur enumerator.Current » de l'appelant, même si la fonction avance recenseur. Je me demandais si quelqu'un sait pourquoi est-ce le cas? Est-ce un recenseur primitif comme un entier, sans référence d'objet, et change donc à elle ne se reflète pas dans l'appelant?
Voici le code exemple:
Cette fonction est byval et se coince dans une boucle infinie, crachant des boîtes de message « 1 », parce que « courant » du recenseur n'avance passé 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
, d'autre part, fonctionne comme on peut s'y attendre:
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
La différence entre les deux fonctions est que si la fonction listFirstItem__ accepte un byval ou un byref recenseur.
La solution
La raison pour laquelle vous voyez ce comportement est que List(Of T).Enumerator
est un Struct
et non un Class
comme on le devrait. Alors, quand vous passez le recenseur vous passez une copie et donc que cette copie est mise à jour lorsque vous appelez MoveNext
Autres conseils
En utilisant le code échantillon fourni ne serait pas compiler en utilisant Option Strict On. La fixation qui peut fixer la différence que vous voyez.
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