Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule pokazano, jak używać IEnumerable
interfejsów i IEnumerator
do tworzenia klasy, której można użyć w instrukcji foreach
.
Oryginalna wersja produktu: Visual Studio
Oryginalny numer KB: 322022
IEnumerator, interfejs
IEnumerable
i IEnumerator
są często używane razem. Chociaż te interfejsy są podobne (i mają podobne nazwy), mają różne cele.
Interfejs IEnumerator
zapewnia iteracyjne możliwości kolekcji, która jest wewnętrzna dla klasy. IEnumerator
wymaga zaimplementowania trzech metod:
Metoda
MoveNext
, która zwiększa indeks kolekcji o 1 i zwraca wartość logiczną wskazującą, czy koniec kolekcji został osiągnięty.Metoda
Reset
, która resetuje indeks kolekcji do początkowej wartości -1. Spowoduje to unieważnienie modułu wyliczającego.Metoda
Current
, która zwraca bieżący obiekt pod adresemposition
.public bool MoveNext() { position++; return (position < carlist.Length); } public void Reset() { position = -1; } public object Current { get { return carlist[position];} }
IEnumerable, interfejs
Interfejs IEnumerable
zapewnia obsługę foreach
iteracji. IEnumerable
wymaga zaimplementowania GetEnumerator
metody .
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
Kiedy używać interfejsu
Początkowo może się okazać, że korzystanie z tych interfejsów jest mylące. Interfejs IEnumerator
zapewnia iterację obiektu typu kolekcji w klasie. Interfejs IEnumerable
zezwala na wyliczanie przy użyciu foreach
pętli. GetEnumerator
Jednak metoda interfejsu IEnumerable
zwraca IEnumerator
interfejs. Aby zaimplementować IEnumerable
metodę , należy również zaimplementować .IEnumerator
Jeśli nie zaimplementujesz IEnumerator
metody , nie możesz rzutować wartości zwracanej z GetEnumerator
metody IEnumerable
na IEnumerator
interfejs.
Podsumowując, użycie IEnumerable
klasy wymaga zaimplementowania IEnumerator
klasy . Jeśli chcesz zapewnić obsługę programu foreach
, zaimplementuj oba interfejsy.
Przykład krok po kroku
W poniższym przykładzie pokazano, jak używać tych interfejsów. W tym przykładzie IEnumerator
interfejsy i IEnumerable
są używane w klasie o nazwie cars
. Klasa cars
ma wewnętrzną tablicę car
obiektów. Aplikacje klienckie mogą wyliczać za pomocą tej tablicy wewnętrznej przy użyciu foreach
konstrukcji ze względu na implementację tych dwóch interfejsów.
Wykonaj następujące kroki, aby utworzyć nowy projekt aplikacja konsolowa w programie Visual C#:
- Uruchom program Microsoft Visual Studio .NET lub Visual Studio.
- W menu Plik wskaż polecenie Nowy, a następnie kliknij Projekt.
- Kliknij Projekty Visual C# w sekcji Rodzaje projektów, a następnie kliknij Aplikacja konsoli w sekcji Szablony.
- W polu Nazwa wpisz ConsoleEnum.
Zmień nazwę Class1.cs na host.cs, a następnie zastąp kod w host.cs następującym kodem:
using System; namespace ConsoleEnum { class host { [STAThread] static void Main(string[] args) { cars C = new cars(); Console.WriteLine("\nInternal Collection (Unsorted - IEnumerable,Enumerator)\n"); foreach(car c in C) Console.WriteLine(c.Make + "\t\t" + c.Year); Console.ReadLine(); } } }
W menu Projekt kliknij pozycję Dodaj klasę, a następnie wpisz samochód w polu Nazwa.
Zastąp kod w car.cs następującym kodem:
using System; using System.Collections; namespace ConsoleEnum { public class car { private int year; private string make; public car(string Make,int Year) { make=Make; year=Year; } public int Year { get {return year;} set {year=value;} } public string Make { get {return make;} set {make=value;} } }//end class }//end namespace
W menu Projekt kliknij pozycję Dodaj klasę, aby dodać kolejną klasę do projektu, a następnie wpisz samochody w polu Nazwa.
Zastąp kod w cars.cs następującym kodem:
using System; using System.Collections; namespace ConsoleEnum { public class cars : IEnumerator,IEnumerable { private car[] carlist; int position = -1; //Create internal array in constructor. public cars() { carlist= new car[6] { new car("Ford",1992), new car("Fiat",1988), new car("Buick",1932), new car("Ford",1932), new car("Dodge",1999), new car("Honda",1977) }; } //IEnumerator and IEnumerable require these methods. public IEnumerator GetEnumerator() { return (IEnumerator)this; } //IEnumerator public bool MoveNext() { position++; return (position < carlist.Length); } //IEnumerable public void Reset() { position = -1; } //IEnumerable public object Current { get { return carlist[position];} } } }
Uruchamianie projektu.
Następujące dane wyjściowe są wyświetlane w oknie Konsola :
Ford 1992
Fiat 1988
Buick 1932
Ford 1932
Dodge 1999
Honda 1977
Najlepsze rozwiązania
Przykład w tym artykule jest możliwie najprostszy, aby lepiej wyjaśnić użycie tych interfejsów. Aby kod był bardziej niezawodny i upewnić się, że kod korzysta z bieżących wytycznych dotyczących najlepszych rozwiązań, zmodyfikuj kod w następujący sposób:
- Zaimplementuj
IEnumerator
w zagnieżdżonej klasie, aby można było utworzyć wiele modułów wyliczających. - Podaj obsługę wyjątków
IEnumerator
dlaCurrent
metody . Jeśli zawartość kolekcji ulegnie zmianie, wywoływanareset
jest metoda . W związku z tym bieżący moduł wyliczający jest unieważniany i otrzymujeszIndexOutOfRangeException
wyjątek. Inne okoliczności mogą również spowodować ten wyjątek. Dlatego zaimplementuj blok,Try...Catch
aby przechwycić ten wyjątek i zgłosićInvalidOperationException
wyjątek.
using System;
using System.Collections;
namespace ConsoleEnum
{
public class cars : IEnumerable
{
private car[] carlist;
//Create internal array in constructor.
public cars()
{
carlist= new car[6]
{
new car("Ford",1992),
new car("Fiat",1988),
new car("Buick",1932),
new car("Ford",1932),
new car("Dodge",1999),
new car("Honda",1977)
};
}
//private enumerator class
private class MyEnumerator:IEnumerator
{
public car[] carlist;
int position = -1;
//constructor
public MyEnumerator(car[] list)
{
carlist=list;
}
private IEnumerator getEnumerator()
{
return (IEnumerator)this;
}
//IEnumerator
public bool MoveNext()
{
position++;
return (position < carlist.Length);
}
//IEnumerator
public void Reset()
{
position = -1;
}
//IEnumerator
public object Current
{
get
{
try
{
return carlist[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
} //end nested class
public IEnumerator GetEnumerator()
{
return new MyEnumerator(carlist);
}
}
}