programowanieDeweloper VB.NET, Deweloper Backend

Jak działają pętle For Each w Visual Basic? Jakie są różnice w porównaniu do For i While, jakich obiektów można używać w ten sposób i jakie pułapki mogą wystąpić w przypadku zmiany kolekcji w pętli?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

Pętla For Each w Visual Basic służy do sekwencyjnego przeglądania wszystkich elementów kolekcji lub tablicy. Jej użycie ułatwia pracę z obiektami, które można wyliczać (Collection, Array, listy itp.), nie wymagając bezpośredniego odwoływania się do indeksów.

Składnia:

For Each element As DataType In collection ' Działania z elementem Next

Różnice w porównaniu do innych pętli:

  • For — wymaga podania liczników i zakresu, skuteczny, gdy konieczny jest dostęp do elementów za pomocą indeksów.
  • While — wykonuje się, dopóki warunek jest prawdziwy, przydatny do nieprzewidywalnej liczby iteracji.
  • For Each — iteruje przez wszystkie elementy bez dostępu do indeksów, nadaje się do nowoczesnych kolekcji.

Ograniczenia i cechy For Each:

  • Nie można bezpośrednio zmieniać elementów kolekcji (szczególnie jeśli kolekcja jest niemodyfikowalna lub strukturalna).
  • Kolekcja musi implementować interfejs IEnumerable.
  • W przypadku zmiany kolekcji (dodawanie/usuwanie elementów) podczas pętli może wystąpić wyjątek InvalidOperationException.

Przykład:

Dim items As New List(Of Integer)({1, 2, 3}) For Each item As Integer In items Console.WriteLine(item) Next

Próba zmiany kolekcji wewnątrz pętli może spowodować błąd:

For Each item As Integer In items If item = 2 Then items.Remove(item) ' Wyjątek! End If Next

Pytanie z podstępem

Czy można zmieniać elementy kolekcji przez wartość, używając For Each, jeśli elementy są strukturami?

Nie, jeśli elementy kolekcji są strukturami (typy wartości), zmienna iteracyjna w For Each zawiera kopię wartości. Jakiekolwiek zmiany w zmiennej nie wpłyną na rzeczywisty element kolekcji. Na przykład:

Structure Point Public X As Integer End Structure Dim points As New List(Of Point)({New Point With {.X = 1}}) For Each pt In points pt.X = 100 ' Nie zmienia points(0).X Next

Przykłady faktycznych błędów z powodu nieznajomości subtelności tematu


Historia

W projekcie używano For Each do zmiany pól struktur pracownika. Iteracja nie zmieniała danych źródłowych, ponieważ obiekt iteracyjny był kopią, a nie samym elementem kolekcji. Z tego powodu aktualizacja wynagrodzeń nie działała.


Historia

Podczas przeglądania listy w For Each usuwano elementy w warunku — w wyniku czego aplikacja wyrzucała InvalidOperationException i kończyła działanie.


Historia

Przeglądanie kolekcji przez For Each bez uwzględnienia jej zmienności doprowadziło do nieskończonej pętli, gdy zewnętrzne źródło danych równocześnie napełniało tę kolekcję podczas jej odczytu, powodując błędy logiczne w obliczeniach.