IEnumerator Interfejs

Definicja

Obsługuje prostą iterację w kolekcji innej niż ogólna.

C#
public interface IEnumerator
C#
[System.Runtime.InteropServices.Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerator
C#
[System.Runtime.InteropServices.Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
[System.Runtime.InteropServices.ComVisible(true)]
public interface IEnumerator
Pochodne
Atrybuty

Przykłady

Poniższy przykład kodu przedstawia implementację interfejsów IEnumerable i IEnumerator dla kolekcji niestandardowej. W tym przykładzie elementy członkowskie tych interfejsów nie są jawnie wywoływane, ale są implementowane w celu obsługi korzystania z foreach (for each w Visual Basic) w celu iteracji w kolekcji.

C#
using System;
using System.Collections;

// Simple business object.
public class Person
{
    public Person(string fName, string lName)
    {
        this.firstName = fName;
        this.lastName = lName;
    }

    public string firstName;
    public string lastName;
}

// Collection of Person objects. This class
// implements IEnumerable so that it can be used
// with ForEach syntax.
public class People : IEnumerable
{
    private Person[] _people;
    public People(Person[] pArray)
    {
        _people = new Person[pArray.Length];

        for (int i = 0; i < pArray.Length; i++)
        {
            _people[i] = pArray[i];
        }
    }

// Implementation for the GetEnumerator method.
    IEnumerator IEnumerable.GetEnumerator()
    {
       return (IEnumerator) GetEnumerator();
    }

    public PeopleEnum GetEnumerator()
    {
        return new PeopleEnum(_people);
    }
}

// When you implement IEnumerable, you must also implement IEnumerator.
public class PeopleEnum : IEnumerator
{
    public Person[] _people;

    // Enumerators are positioned before the first element
    // until the first MoveNext() call.
    int position = -1;

    public PeopleEnum(Person[] list)
    {
        _people = list;
    }

    public bool MoveNext()
    {
        position++;
        return (position < _people.Length);
    }

    public void Reset()
    {
        position = -1;
    }

    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }

    public Person Current
    {
        get
        {
            try
            {
                return _people[position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}

class App
{
    static void Main()
    {
        Person[] peopleArray = new Person[3]
        {
            new Person("John", "Smith"),
            new Person("Jim", "Johnson"),
            new Person("Sue", "Rabon"),
        };

        People peopleList = new People(peopleArray);
        foreach (Person p in peopleList)
            Console.WriteLine(p.firstName + " " + p.lastName);
    }
}

/* This code produces output similar to the following:
 *
 * John Smith
 * Jim Johnson
 * Sue Rabon
 *
 */

Uwagi

IEnumerator jest interfejsem podstawowym dla wszystkich niegenerycznych modułów wyliczania. Jego ogólny odpowiednik jest interfejsem System.Collections.Generic.IEnumerator<T>.

Instrukcja foreach języka C# (for each w Visual Basic) ukrywa złożoność modułów wyliczania. Dlatego użycie foreach jest zalecane zamiast bezpośredniego manipulowania modułem wyliczającym.

Moduły wyliczania mogą służyć do odczytywania danych w kolekcji, ale nie mogą być używane do modyfikowania podstawowej kolekcji.

Metoda Reset jest zapewniana na potrzeby współdziałania modelu COM i nie musi być w pełni zaimplementowana; Zamiast tego implementator może zgłosić NotSupportedException.

Początkowo moduł wyliczający jest umieszczony przed pierwszym elementem w kolekcji. Przed odczytaniem wartości Currentnależy wywołać metodę MoveNext, aby przejść moduł wyliczający do pierwszego elementu kolekcji; w przeciwnym razie Current jest niezdefiniowany.

Current zwraca ten sam obiekt do momentu wywołania MoveNext lub Reset. MoveNext ustawia Current na następny element.

Jeśli MoveNext przechodzi na końcu kolekcji, moduł wyliczający jest umieszczony po ostatnim elemenie w kolekcji i MoveNext zwraca wartość false. Gdy moduł wyliczający znajduje się na tym stanowisku, kolejne wywołania MoveNext również zwracają false. Jeśli ostatnie wywołanie MoveNext zwróciło false, Current jest niezdefiniowany.

Aby ponownie ustawić Current na pierwszy element kolekcji, możesz wywołać Reset, jeśli została zaimplementowana, a następnie MoveNext. Jeśli Reset nie jest zaimplementowana, należy utworzyć nowe wystąpienie modułu wyliczającego, aby powrócić do pierwszego elementu kolekcji.

Jeśli zmiany są wprowadzane do kolekcji, takie jak dodawanie, modyfikowanie lub usuwanie elementów, zachowanie modułu wyliczającego jest niezdefiniowane.

Moduł wyliczający nie ma wyłącznego dostępu do kolekcji; w związku z tym wyliczanie za pośrednictwem kolekcji nie jest wewnętrznie procedurą bezpieczną wątkowo. Nawet w przypadku synchronizacji kolekcji inne wątki nadal mogą modyfikować kolekcję, co powoduje zgłoszenie wyjątku przez moduł wyliczający. Aby zagwarantować bezpieczeństwo wątków podczas wyliczania, możesz zablokować kolekcję podczas całego wyliczenia lub przechwycić wyjątki wynikające ze zmian wprowadzonych przez inne wątki.

Właściwości

Current

Pobiera element w kolekcji na bieżącej pozycji modułu wyliczającego.

Metody

MoveNext()

Przechodzi moduł wyliczający do następnego elementu kolekcji.

Reset()

Ustawia moduł wyliczający na swoją początkową pozycję, która znajduje się przed pierwszym elementem w kolekcji.

Dotyczy

Produkt Wersje
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

Zobacz też