Rendere utilizzabile una classe Visual C# in un'istruzione foreach
Questo articolo illustra come usare le IEnumerable
interfacce e IEnumerator
per creare una classe che è possibile usare in un'istruzione foreach
.
Versione originale del prodotto: Visual Studio
Numero KB originale: 322022
Interfaccia IEnumerator
IEnumerable
e IEnumerator
vengono spesso usati insieme. Anche se queste interfacce sono simili (e hanno nomi simili), hanno scopi diversi.
L'interfaccia IEnumerator
fornisce funzionalità iterative per una raccolta interna a una classe. IEnumerator
richiede l'implementazione di tre metodi:
Il
MoveNext
metodo , che incrementa l'indice della raccolta di 1 e restituisce un valore bool che indica se è stata raggiunta la fine della raccolta.Metodo
Reset
che reimposta l'indice della raccolta sul valore iniziale di -1. Ciò invalida l'enumeratore.Metodo
Current
, che restituisce l'oggetto corrente in corrispondenza diposition
.public bool MoveNext() { position++; return (position < carlist.Length); } public void Reset() { position = -1; } public object Current { get { return carlist[position];} }
Interfaccia IEnumerable
L'interfaccia IEnumerable
fornisce il supporto per l'iterazione foreach
. IEnumerable
richiede l'implementazione del GetEnumerator
metodo .
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
Quando usare l'interfaccia
Inizialmente, l'uso di queste interfacce potrebbe creare confusione. L'interfaccia IEnumerator
fornisce l'iterazione su un oggetto di tipo raccolta in una classe. L'interfaccia IEnumerable
consente l'enumerazione tramite un foreach
ciclo . Tuttavia, il GetEnumerator
metodo dell'interfaccia IEnumerable
restituisce un'interfaccia IEnumerator
. Per implementare IEnumerable
, è quindi necessario implementare IEnumerator
anche . Se non si implementa IEnumerator
, non è possibile eseguire il cast del valore restituito dal GetEnumerator
metodo di IEnumerable
all'interfaccia IEnumerator
.
In sintesi, l'uso di IEnumerable
richiede che la classe implementi IEnumerator
. Se si vuole fornire il supporto per foreach
, implementare entrambe le interfacce.
Esempio dettagliato
Nell'esempio seguente viene illustrato come usare queste interfacce. In questo esempio le IEnumerator
interfacce e IEnumerable
vengono usate in una classe denominata cars
. La cars
classe ha una matrice interna di car
oggetti . Le applicazioni client possono enumerare tramite questa matrice interna usando un foreach
costrutto a causa dell'implementazione di queste due interfacce.
Seguire questa procedura per creare un nuovo progetto applicazione console in Visual C#:
- Avviare Microsoft Visual Studio .NET o Visual Studio.
- Scegliere Nuovo dal menu File, quindi fare clic su Progetto.
- Fare clic su Progetti Visual C# in Tipi di progetto e quindi su Applicazione console in Modelli.
- Nella casella Nome digitare ConsoleEnum.
Rinominare Class1.cs in host.cs e quindi sostituire il codice in host.cs con il codice seguente:
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(); } } }
Scegliere Aggiungi classe dal menu Progetto e quindi digitare l'auto nella casella Nome.
Sostituire il codice in car.cs con il codice seguente:
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
Scegliere Aggiungi classe dal menu Progetto per aggiungere un'altra classe al progetto e quindi digitare automobili nella casella Nome.
Sostituire il codice in cars.cs con il codice seguente:
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];} } } }
Eseguire il progetto.
Nella finestra Console viene visualizzato l'output seguente:
Ford 1992
Fiat 1988
Buick 1932
Ford 1932
Dodge 1999
Honda 1977
Procedure consigliate
L'esempio in questo articolo viene mantenuto il più semplice possibile per spiegare meglio l'uso di queste interfacce. Per rendere il codice più affidabile e assicurarsi che il codice usi le linee guida sulle procedure consigliate correnti, modificare il codice come indicato di seguito:
- Implementare
IEnumerator
in una classe annidata in modo che sia possibile creare più enumeratori. - Fornire la gestione delle eccezioni per il
Current
metodo diIEnumerator
. Se il contenuto della raccolta cambia, viene chiamato ilreset
metodo . Di conseguenza, l'enumeratore corrente viene invalidato e si riceve un'eccezioneIndexOutOfRangeException
. Anche altre circostanze potrebbero causare questa eccezione. Implementare quindi unTry...Catch
blocco per intercettare questa eccezione e generare un'eccezioneInvalidOperationException
.
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);
}
}
}
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: nel corso del 2024 verranno dismessi i problemi di GitHub come meccanismo di feedback per il contenuto e verranno sostituiti con un nuovo sistema di feedback. Per altre informazioni, vedere:Invia e visualizza il feedback per