For Each...Next — Instrukcja (Visual Basic)For Each...Next Statement (Visual Basic)

Powtarza grupę instrukcji dla każdego elementu w kolekcji.Repeats a group of statements for each element in a collection.

SkładniaSyntax

For Each element [ As datatype ] In group
    [ statements ]
    [ Continue For ]
    [ statements ]
    [ Exit For ]
    [ statements ]
Next [ element ]

CzęściParts

TerminTerm DefinicjaDefinition
element Wymagane w For Each instrukcji.Required in the For Each statement. Opcjonalne w Next instrukcji.Optional in the Next statement. Zmiennej.Variable. Służy do iteracji elementów kolekcji.Used to iterate through the elements of the collection.
datatype Opcjonalne Jeśli Option Infer jest włączone (wartość domyślna) lub element jest już zadeklarowane; wymagane, jeśli Option Infer jest wyłączone i element nie jest już zadeklarowane.Optional if Option Infer is on (the default) or element is already declared; required if Option Infer is off and element isn't already declared. Typ danych element .The data type of element.
group Wymagany.Required. Zmienna z typem, który jest typem kolekcji lub obiektem.A variable with a type that's a collection type or Object. Odwołuje się do kolekcji, w której mają statements być powtarzane.Refers to the collection over which the statements are to be repeated.
statements Opcjonalny.Optional. Co najmniej jedna instrukcja między For Each i Next , która jest uruchamiana dla każdego elementu w group .One or more statements between For Each and Next that run on each item in group.
Continue For Opcjonalny.Optional. Przenosi kontrolę na początek For Each pętli.Transfers control to the start of the For Each loop.
Exit For Opcjonalny.Optional. Przenosi kontrolę z For Each pętli.Transfers control out of the For Each loop.
Next Wymagany.Required. Kończy definicję For Each pętli.Terminates the definition of the For Each loop.

Prosty przykładSimple Example

Użyj For Each pętli... Next , jeśli chcesz powtórzyć zestaw instrukcji dla każdego elementu kolekcji lub tablicy.Use a For Each...Next loop when you want to repeat a set of statements for each element of a collection or array.

Porada

A dla... Następna instrukcja działa prawidłowo, gdy można skojarzyć każdą iterację pętli z zmienną kontroli i określić początkową i końcową wartość tej zmiennej.A For...Next Statement works well when you can associate each iteration of a loop with a control variable and determine that variable's initial and final values. Jednak podczas pracy z kolekcją pojęcie wartości początkowych i końcowych nie ma znaczenia, a użytkownik nie musi wiedzieć, ile elementów ma kolekcja.However, when you are dealing with a collection, the concept of initial and final values isn't meaningful, and you don't necessarily know how many elements the collection has. W tym rodzaju przypadku For Each pętla... Next jest często lepszym wyborem.In this kind of case, a For Each...Next loop is often a better choice.

W poniższym przykładzie,.. For Each .NextIn the following example, the For EachNext instrukcja wykonuje iterację przez wszystkie elementy kolekcji list.statement iterates through all the elements of a List collection.

' Create a list of strings by using a
' collection initializer.
Dim lst As New List(Of String) _
    From {"abc", "def", "ghi"}

' Iterate through the list.
For Each item As String In lst
    Debug.Write(item & " ")
Next
Debug.WriteLine("")
'Output: abc def ghi

Aby uzyskać więcej przykładów, zobacz kolekcje i tablice.For more examples, see Collections and Arrays.

Pętle zagnieżdżoneNested Loops

Pętle można zagnieżdżać For Each , umieszczając jedną pętlę w innej.You can nest For Each loops by putting one loop within another.

W poniższym przykładzie pokazano zagnieżdżonych For Each ...NextThe following example demonstrates nested For EachNext ds.structures.

' Create lists of numbers and letters
' by using array initializers.
Dim numbers() As Integer = {1, 4, 7}
Dim letters() As String = {"a", "b", "c"}

' Iterate through the list by using nested loops.
For Each number As Integer In numbers
    For Each letter As String In letters
        Debug.Write(number.ToString & letter & " ")
    Next
Next
Debug.WriteLine("")
'Output: 1a 1b 1c 4a 4b 4c 7a 7b 7c 

Podczas zagnieżdżania pętli Każda pętla musi mieć unikatową element zmienną.When you nest loops, each loop must have a unique element variable.

Można również zagnieżdżać różne rodzaje struktur kontroli w obrębie siebie.You can also nest different kinds of control structures within each other. Aby uzyskać więcej informacji, zobacz struktury formantów zagnieżdżonych.For more information, see Nested Control Structures.

Zamknij i Kontynuuj dlaExit For and Continue For

Instrukcja Exit for powoduje wyjście z For ...NextThe Exit For statement causes execution to exit the ForNext Pętla i przeniesie sterowanie do instrukcji, która następuje po Next instrukcji.loop and transfers control to the statement that follows the Next statement.

Continue ForInstrukcja natychmiast przenosi kontrolę do następnej iteracji pętli.The Continue For statement transfers control immediately to the next iteration of the loop. Aby uzyskać więcej informacji, zobacz Kontynuacja instrukcji.For more information, see Continue Statement.

Poniższy przykład pokazuje, jak używać Continue For Exit For instrukcji i.The following example shows how to use the Continue For and Exit For statements.

Dim numberSeq() As Integer =
    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}

For Each number As Integer In numberSeq
    ' If number is between 5 and 7, continue
    ' with the next iteration.
    If number >= 5 And number <= 8 Then
        Continue For
    End If

    ' Display the number.
    Debug.Write(number.ToString & " ")

    ' If number is 10, exit the loop.
    If number = 10 Then
        Exit For
    End If
Next
Debug.WriteLine("")
' Output: 1 2 3 4 9 10

W pętli można umieścić dowolną liczbę Exit For instrukcji For Each .You can put any number of Exit For statements in a For Each loop. W przypadku użycia w For Each pętlach zagnieżdżonych Exit For powoduje wyjście z wewnętrznej pętli i przeniesienie kontroli do następnego wyższego poziomu zagnieżdżenia.When used within nested For Each loops, Exit For causes execution to exit the innermost loop and transfers control to the next higher level of nesting.

Exit Forjest często używany po ocenie pewnego stanu, na przykład w If ... Then ...Else XML.Exit For is often used after an evaluation of some condition, for example, in an If...Then...Else structure. Może być konieczne użycie Exit For następujących warunków:You might want to use Exit For for the following conditions:

  • Kontynuowanie iteracji jest niepotrzebne lub niemożliwe.Continuing to iterate is unnecessary or impossible. Może to być spowodowane błędną wartością lub żądaniem zakończenia.This might be caused by an erroneous value or a termination request.

  • Wyjątek jest przechwytywany w Try ... Catch ...Finally. Możesz użyć Exit For na końcu Finally bloku.An exception is caught in a Try...Catch...Finally. You might use Exit For at the end of the Finally block.

  • Istnieje nieskończona pętla, która jest pętlą, która może uruchamiać dużą lub nawet nieskończoną liczbę razy.There an endless loop, which is a loop that could run a large or even infinite number of times. Jeśli wykryjesz taki warunek, możesz użyć, Exit For Aby wyjść z pętli.If you detect such a condition, you can use Exit For to escape the loop. Aby uzyskać więcej informacji, zobacz ... Loop — instrukcja.For more information, see Do...Loop Statement.

IteratoryIterators

Za pomocą iteratora można wykonać niestandardową iterację w kolekcji.You use an iterator to perform a custom iteration over a collection. Iterator może być funkcją lub Get akcesorem.An iterator can be a function or a Get accessor. Używa instrukcji, Yield Aby zwrócić każdy element kolekcji pojedynczo.It uses a Yield statement to return each element of the collection one at a time.

Należy wywołać iterator przy użyciu For Each...Next instrukcji.You call an iterator by using a For Each...Next statement. Każda iteracja For Each pętli wywołuje iterator.Each iteration of the For Each loop calls the iterator. Po Yield osiągnięciu instrukcji w iteratorze Yield zwracane jest wyrażenie w instrukcji, a bieżąca lokalizacja w kodzie jest zachowywana.When a Yield statement is reached in the iterator, the expression in the Yield statement is returned, and the current location in code is retained. Wykonanie jest uruchamiane ponownie z tej lokalizacji przy następnym wywołaniu iteratora.Execution is restarted from that location the next time that the iterator is called.

Poniższy przykład używa funkcji iteratora.The following example uses an iterator function. Funkcja iteratora zawiera Yield instrukcję, która znajduje się wewnątrz elementu ... Następna pętla.The iterator function has a Yield statement that's inside a For…Next loop. W ListEvenNumbers metodzie każda iteracja For Each treści instrukcji tworzy wywołanie funkcji iteratora, która przechodzi do następnej Yield instrukcji.In the ListEvenNumbers method, each iteration of the For Each statement body creates a call to the iterator function, which proceeds to the next Yield statement.

Public Sub ListEvenNumbers()
    For Each number As Integer In EvenSequence(5, 18)
        Debug.Write(number & " ")
    Next
    Debug.WriteLine("")
    ' Output: 6 8 10 12 14 16 18
End Sub

Private Iterator Function EvenSequence(
ByVal firstNumber As Integer, ByVal lastNumber As Integer) _
As System.Collections.Generic.IEnumerable(Of Integer)

    ' Yield even numbers in the range.
    For number = firstNumber To lastNumber
        If number Mod 2 = 0 Then
            Yield number
        End If
    Next
End Function

Aby uzyskać więcej informacji, zobacz Iteratory, instrukcja Yieldi iterator.For more information, see Iterators, Yield Statement, and Iterator.

Realizacja technicznaTechnical Implementation

Gdy For Each ...NextWhen a For EachNext zostanie uruchomiona instrukcja, Visual Basic oblicza tylko jeden raz, zanim zostanie uruchomiona pętla.statement runs, Visual Basic evaluates the collection only one time, before the loop starts. Jeśli instrukcja zablokuje zmiany element lub zmiany group nie wpłyną na iterację pętli.If your statement block changes element or group, these changes don't affect the iteration of the loop.

Gdy wszystkie elementy w kolekcji zostały po raz kolejny przypisane do element , For Each Pętla przestanie działać i kontrola przechodzi do instrukcji następującej po Next instrukcji.When all the elements in the collection have been successively assigned to element, the For Each loop stops and control passes to the statement following the Next statement.

Jeśli opcja wnioskowanie jest włączona (ustawienie domyślne), kompilator Visual Basic może wywnioskować typ danych element .If Option Infer is on (its default setting), the Visual Basic compiler can infer the data type of element. Jeśli jest wyłączona i element nie została zadeklarowana poza pętlą, należy zadeklarować ją w For Each instrukcji.If it is off and element hasn't been declared outside the loop, you must declare it in the For Each statement. Aby jawnie zadeklarować typ danych element , należy użyć As klauzuli.To declare the data type of element explicitly, use an As clause. Chyba że typ danych elementu jest zdefiniowany poza konstrukcja.. For Each . Next , jego zakres jest treścią pętli.Unless the data type of element is defined outside the For Each...Next construct, its scope is the body of the loop. Należy zauważyć, że nie można zadeklarować element jednocześnie zewnątrz i wewnątrz pętli.Note that you cannot declare element both outside and inside the loop.

Opcjonalnie można określić element w Next instrukcji.You can optionally specify element in the Next statement. Poprawia to czytelność programu, zwłaszcza jeśli istnieją zagnieżdżone For Each pętle.This improves the readability of your program, especially if you have nested For Each loops. Należy określić tę samą zmienną, która pojawia się w odpowiedniej For Each instrukcji.You must specify the same variable as the one that appears in the corresponding For Each statement.

Można uniknąć zmiany wartości element wewnątrz pętli.You might want to avoid changing the value of element inside a loop. Może to utrudnić odczytywanie i debugowanie kodu.Doing this can make it more difficult to read and debug your code. Zmiana wartości group nie ma wpływu na kolekcję lub jej elementy, które zostały określone podczas pierwszego wprowadzenia pętli.Changing the value of group doesn't affect the collection or its elements, which were determined when the loop was first entered.

Gdy są zagnieżdżane pętle, jeśli zostanie Next napotkana instrukcja zewnętrznego poziomu zagnieżdżenia przed Next poziomem wewnętrzny, kompilator sygnalizuje błąd.When you're nesting loops, if a Next statement of an outer nesting level is encountered before the Next of an inner level, the compiler signals an error. Jednak kompilator może wykryć ten błąd nakładający się tylko wtedy, gdy określisz element w każdej Next instrukcji.However, the compiler can detect this overlapping error only if you specify element in every Next statement.

Jeśli kod zależy od przechodzenia do kolekcji w określonej kolejności, For Each pętla... Next nie jest najlepszym wyborem, chyba że znane są właściwości obiektu modułu wyliczającego.If your code depends on traversing a collection in a particular order, a For Each...Next loop isn't the best choice, unless you know the characteristics of the enumerator object the collection exposes. Kolejność przechodzenia nie jest określana przez Visual Basic, ale przez MoveNext metodę obiektu modułu wyliczającego.The order of traversal isn't determined by Visual Basic, but by the MoveNext method of the enumerator object. W związku z tym może nie być możliwe przewidywalnie, który element kolekcji jest pierwszy do zwrócenia w element , lub który jest kolejnym, który ma zostać zwrócony po danym elemencie.Therefore, you might not be able to predict which element of the collection is the first to be returned in element, or which is the next to be returned after a given element. Możesz uzyskać bardziej niezawodne wyniki przy użyciu innej struktury pętli, takiej jak For ... Next lub Do . Loop ..You might achieve more reliable results using a different loop structure, such as For...Next or Do...Loop.

Środowisko uruchomieniowe musi mieć możliwość konwersji elementów w group na element .The runtime must be able to convert the elements in group to element. Instrukcja [ Option Strict ] kontroluje, czy dozwolone są zarówno konwersje rozszerzające, jak i wąskie ( Option Strict jest wyłączone, jego wartość domyślna) czy dozwolone są tylko konwersje rozszerzające ( Option Strict jest on włączony).The [Option Strict] statement controls whether both widening and narrowing conversions are allowed (Option Strict is off, its default value), or whether only widening conversions are allowed (Option Strict is on). Aby uzyskać więcej informacji, zobacz temat zwężanie konwersji.For more information, see Narrowing conversions.

Typ danych group musi być typem referencyjnym, który odwołuje się do kolekcji lub tablicy, która jest wyliczalna.The data type of group must be a reference type that refers to a collection or an array that's enumerable. Najczęściej oznacza to, że group odwołuje się do obiektu, który implementuje IEnumerable Interfejs System.Collections przestrzeni nazw lub IEnumerable<T> Interfejs System.Collections.Generic przestrzeni nazw.Most commonly this means that group refers to an object that implements the IEnumerable interface of the System.Collections namespace or the IEnumerable<T> interface of the System.Collections.Generic namespace. System.Collections.IEnumerabledefiniuje GetEnumerator metodę, która zwraca obiekt modułu wyliczającego dla kolekcji.System.Collections.IEnumerable defines the GetEnumerator method, which returns an enumerator object for the collection. Obiekt Enumerator implementuje System.Collections.IEnumerator Interfejs System.Collections przestrzeni nazw i uwidacznia Current Właściwość oraz Reset MoveNext metody i.The enumerator object implements the System.Collections.IEnumerator interface of the System.Collections namespace and exposes the Current property and the Reset and MoveNext methods. Visual Basic używa ich do przechodzenia do kolekcji.Visual Basic uses these to traverse the collection.

Konwersje zawężająceNarrowing Conversions

Gdy Option Strict jest ustawiona na On , zawężanie konwersji zwykle powoduje błędy kompilatora.When Option Strict is set to On, narrowing conversions ordinarily cause compiler errors. Jednakże w For Each instrukcji konwersje z elementów w group do element są oceniane i wykonywane w czasie wykonywania, a błędy kompilatora spowodowane przez zawężanie konwersji są pomijane.In a For Each statement, however, conversions from the elements in group to element are evaluated and performed at run time, and compiler errors caused by narrowing conversions are suppressed.

W poniższym przykładzie przypisanie m jako wartość początkowa dla elementu n nie kompiluje, gdy Option Strict jest włączone, ponieważ konwersja Long do a Integer jest konwersją wąskią.In the following example, the assignment of m as the initial value for n doesn't compile when Option Strict is on because the conversion of a Long to an Integer is a narrowing conversion. W For Each instrukcji nie jest jednak raportowany błąd kompilatora, mimo że przypisanie do number wymaga tej samej konwersji z Long do Integer .In the For Each statement, however, no compiler error is reported, even though the assignment to number requires the same conversion from Long to Integer. W instrukcji zawierającej For Each dużą liczbę błąd czasu wykonywania występuje, gdy ToInteger jest stosowany do dużej liczby.In the For Each statement that contains a large number, a run-time error occurs when ToInteger is applied to the large number.

Option Strict On

Module Module1
    Sub Main()
        ' The assignment of m to n causes a compiler error when 
        ' Option Strict is on.
        Dim m As Long = 987
        'Dim n As Integer = m

        ' The For Each loop requires the same conversion but
        ' causes no errors, even when Option Strict is on.
        For Each number As Integer In New Long() {45, 3, 987}
            Console.Write(number & " ")
        Next
        Console.WriteLine()
        ' Output: 45 3 987

        ' Here a run-time error is raised because 9876543210
        ' is too large for type Integer.
        'For Each number As Integer In New Long() {45, 3, 9876543210}
        '    Console.Write(number & " ")
        'Next

        Console.ReadKey()
    End Sub
End Module

Wywołania IEnumeratorIEnumerator Calls

Po For Each uruchomieniu pętli... Next pętla Visual Basic sprawdza, czy group odwołuje się do prawidłowego obiektu kolekcji.When execution of a For Each...Next loop starts, Visual Basic verifies that group refers to a valid collection object. Jeśli nie, zgłasza wyjątek.If not, it throws an exception. W przeciwnym razie wywołuje MoveNext metodę i Current właściwość obiektu modułu wyliczającego w celu zwrócenia pierwszego elementu.Otherwise, it calls the MoveNext method and the Current property of the enumerator object to return the first element. Jeśli MoveNext wskazuje, że nie ma następnego elementu, czyli jeśli kolekcja jest pusta, For Each Pętla przestanie działać i kontrola przechodzi do instrukcji następującej po Next instrukcji.If MoveNext indicates that there is no next element, that is, if the collection is empty, the For Each loop stops and control passes to the statement following the Next statement. W przeciwnym razie Visual Basic ustawia jako element pierwszy element i uruchamia blok instrukcji.Otherwise, Visual Basic sets element to the first element and runs the statement block.

Za każdym razem, gdy Visual Basic napotka Next instrukcję, wraca do For Each instrukcji.Each time Visual Basic encounters the Next statement, it returns to the For Each statement. Ponownie wywołuje MoveNext i Current zwraca następny element, a następnie ponownie uruchamia blok lub przerywa pętlę w zależności od wyniku.Again it calls MoveNext and Current to return the next element, and again it either runs the block or stops the loop depending on the result. Ten proces jest kontynuowany do momentu MoveNext , gdy nie ma żadnego elementu Next ani Exit For instrukcji.This process continues until MoveNext indicates that there is no next element or an Exit For statement is encountered.

Modyfikowanie kolekcji.Modifying the Collection. Obiekt modułu wyliczającego zwrócony przez GetEnumerator zwykle nie pozwala na zmianę kolekcji poprzez dodanie, usunięcie, zastąpienie lub zmianę kolejności elementów.The enumerator object returned by GetEnumerator normally doesn't let you change the collection by adding, deleting, replacing, or reordering any elements. W przypadku zmiany kolekcji po zainicjowaniu For Each pętli... Next obiekt modułu wyliczającego jest nieprawidłowy, a kolejna próba uzyskania dostępu do elementu powoduje InvalidOperationException wyjątek.If you change the collection after you have initiated a For Each...Next loop, the enumerator object becomes invalid, and the next attempt to access an element causes an InvalidOperationException exception.

Jednak ten blok modyfikacji nie jest określany przez Visual Basic, ale raczej przez implementację IEnumerable interfejsu.However, this blocking of modification isn't determined by Visual Basic, but rather by the implementation of the IEnumerable interface. Istnieje możliwość wdrożenia IEnumerable w sposób umożliwiający modyfikację podczas iteracji.It is possible to implement IEnumerable in a way that allows for modification during iteration. Jeśli rozważasz taką modyfikację dynamiczną, upewnij się, że rozumiesz charakterystykę IEnumerable implementacji w używanej kolekcji.If you are considering doing such dynamic modification, make sure that you understand the characteristics of the IEnumerable implementation on the collection you are using.

Modyfikowanie elementów kolekcji.Modifying Collection Elements. CurrentWłaściwość obiektu Enumerator jest tylko do odczytui zwraca lokalną kopię każdego elementu kolekcji.The Current property of the enumerator object is ReadOnly, and it returns a local copy of each collection element. Oznacza to, że nie można modyfikować samych elementów w For Each pętli... Next .This means that you cannot modify the elements themselves in a For Each...Next loop. Wszelkie wprowadzone zmiany mają wpływ tylko na kopię lokalną z Current i nie są odzwierciedlone w źródłowej kolekcji.Any modification you make affects only the local copy from Current and isn't reflected back into the underlying collection. Jeśli jednak element jest typem referencyjnym, można modyfikować członków wystąpienia, do którego wskazuje.However, if an element is a reference type, you can modify the members of the instance to which it points. Poniższy przykład modyfikuje BackColor element członkowski każdego thisControl elementu.The following example modifies the BackColor member of each thisControl element. Nie można jednak modyfikować thisControl samego siebie.You cannot, however, modify thisControl itself.

Sub LightBlueBackground(thisForm As System.Windows.Forms.Form)
    For Each thisControl In thisForm.Controls
        thisControl.BackColor = System.Drawing.Color.LightBlue
    Next thisControl
End Sub

Poprzedni przykład może zmodyfikować BackColor składową każdego thisControl elementu, chociaż nie może on modyfikować thisControl samego siebie.The previous example can modify the BackColor member of each thisControl element, although it cannot modify thisControl itself.

Przechodzenie między tablicami.Traversing Arrays. Ponieważ Array Klasa implementuje IEnumerable interfejs, wszystkie tablice uwidaczniają GetEnumerator metodę.Because the Array class implements the IEnumerable interface, all arrays expose the GetEnumerator method. Oznacza to, że można wykonać iterację tablicy z For Each pętlą.... NextThis means that you can iterate through an array with a For Each...Next loop. Można jednak tylko odczytać elementy tablicy.However, you can only read the array elements. Nie można ich zmienić.You cannot change them.

PrzykładExample

Poniższy przykład wyświetla listę wszystkich folderów w C:\ Katalog przy użyciu DirectoryInfo klasy.The following example lists all the folders in the C:\ directory by using the DirectoryInfo class.

Dim dInfo As New System.IO.DirectoryInfo("c:\")
For Each dir As System.IO.DirectoryInfo In dInfo.GetDirectories()
    Debug.WriteLine(dir.Name)
Next

PrzykładExample

Poniższy przykład ilustruje procedurę sortowania kolekcji.The following example illustrates a procedure for sorting a collection. Przykład sortuje wystąpienia Car klasy, które są przechowywane w List<T> .The example sorts instances of a Car class that are stored in a List<T>. CarKlasa implementuje IComparable<T> interfejs, który wymaga, aby CompareTo Metoda została zaimplementowana.The Car class implements the IComparable<T> interface, which requires that the CompareTo method be implemented.

Każde wywołanie CompareTo metody wykonuje pojedyncze porównanie, które jest używane do sortowania.Each call to the CompareTo method makes a single comparison that's used for sorting. Kod pisany przez użytkownika w CompareTo metodzie zwraca wartość dla każdego porównania bieżącego obiektu z innym obiektem.User-written code in the CompareTo method returns a value for each comparison of the current object with another object. Zwracana wartość jest mniejsza niż zero, jeśli bieżący obiekt jest mniejszy niż inny obiekt, większy niż zero, jeśli bieżący obiekt jest większy niż inny obiekt, i zero, jeśli są równe.The value returned is less than zero if the current object is less than the other object, greater than zero if the current object is greater than the other object, and zero if they are equal. Dzięki temu można zdefiniować w kodzie kryteria dla wartości większej niż, mniejszej niż i równej.This enables you to define in code the criteria for greater than, less than, and equal.

W ListCars metodzie cars.Sort() instrukcja sortuje listę.In the ListCars method, the cars.Sort() statement sorts the list. To wywołanie Sort metody List<T> powoduje CompareTo automatyczne wywoływanie metody dla Car obiektów w obiekcie List .This call to the Sort method of the List<T> causes the CompareTo method to be called automatically for the Car objects in the List.

Public Sub ListCars()

    ' Create some new cars.
    Dim cars As New List(Of Car) From
    {
        New Car With {.Name = "car1", .Color = "blue", .Speed = 20},
        New Car With {.Name = "car2", .Color = "red", .Speed = 50},
        New Car With {.Name = "car3", .Color = "green", .Speed = 10},
        New Car With {.Name = "car4", .Color = "blue", .Speed = 50},
        New Car With {.Name = "car5", .Color = "blue", .Speed = 30},
        New Car With {.Name = "car6", .Color = "red", .Speed = 60},
        New Car With {.Name = "car7", .Color = "green", .Speed = 50}
    }

    ' Sort the cars by color alphabetically, and then by speed
    ' in descending order.
    cars.Sort()

    ' View all of the cars.
    For Each thisCar As Car In cars
        Debug.Write(thisCar.Color.PadRight(5) & " ")
        Debug.Write(thisCar.Speed.ToString & " ")
        Debug.Write(thisCar.Name)
        Debug.WriteLine("")
    Next

    ' Output:
    '  blue  50 car4
    '  blue  30 car5
    '  blue  20 car1
    '  green 50 car7
    '  green 10 car3
    '  red   60 car6
    '  red   50 car2
End Sub

Public Class Car
    Implements IComparable(Of Car)

    Public Property Name As String
    Public Property Speed As Integer
    Public Property Color As String

    Public Function CompareTo(ByVal other As Car) As Integer _
        Implements System.IComparable(Of Car).CompareTo
        ' A call to this method makes a single comparison that is
        ' used for sorting.

        ' Determine the relative order of the objects being compared.
        ' Sort by color alphabetically, and then by speed in
        ' descending order.

        ' Compare the colors.
        Dim compare As Integer
        compare = String.Compare(Me.Color, other.Color, True)

        ' If the colors are the same, compare the speeds.
        If compare = 0 Then
            compare = Me.Speed.CompareTo(other.Speed)

            ' Use descending order for speed.
            compare = -compare
        End If

        Return compare
    End Function
End Class

Zobacz teżSee also