Rendre une classe Visual C# utilisable dans une instruction foreach
Cet article explique comment utiliser les IEnumerable
interfaces et IEnumerator
pour créer une classe que vous pouvez utiliser dans une foreach
instruction .
Version de produit d’origine : Visual Studio
Numéro de la base de connaissances d’origine : 322022
Interface IEnumerator
IEnumerable
et IEnumerator
sont fréquemment utilisés ensemble. Bien que ces interfaces soient similaires (et ont des noms similaires), elles ont des objectifs différents.
L’interface IEnumerator
fournit une fonctionnalité itérative pour une collection interne à une classe. IEnumerator
nécessite que vous implémentiez trois méthodes :
La
MoveNext
méthode , qui incrémente l’index de collection de 1 et retourne un bool qui indique si la fin de la collection a été atteinte.La
Reset
méthode , qui rétablit la valeur initiale de l’index de la collection à -1. Cela invalide l’énumérateur.Méthode
Current
, qui retourne l’objet actuel àposition
.public bool MoveNext() { position++; return (position < carlist.Length); } public void Reset() { position = -1; } public object Current { get { return carlist[position];} }
Interface IEnumerable
L’interface IEnumerable
prend en charge l’itération foreach
. IEnumerable
nécessite que vous implémentiez la GetEnumerator
méthode .
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
Quand utiliser quelle interface
Au départ, vous pouvez trouver confus l’utilisation de ces interfaces. L’interface IEnumerator
fournit une itération sur un objet de type collection dans une classe . L’interface IEnumerable
autorise l’énumération à l’aide d’une foreach
boucle. Toutefois, la GetEnumerator
méthode de l’interface IEnumerable
retourne une IEnumerator
interface. Par conséquent, pour implémenter IEnumerable
, vous devez également implémenter IEnumerator
. Si vous n’implémentez IEnumerator
pas , vous ne pouvez pas convertir la valeur de retour de la GetEnumerator
méthode de IEnumerable
vers l’interface IEnumerator
.
En résumé, l’utilisation de IEnumerable
nécessite que la classe implémente IEnumerator
. Si vous souhaitez assurer la prise en charge de foreach
, implémentez les deux interfaces.
Exemple pas à pas
L’exemple suivant montre comment utiliser ces interfaces. Dans cet exemple, les IEnumerator
interfaces et IEnumerable
sont utilisées dans une classe nommée cars
. La cars
classe a un tableau interne d’objets car
. Les applications clientes peuvent énumérer dans ce tableau interne à l’aide d’une foreach
construction en raison de l’implémentation de ces deux interfaces.
Procédez comme suit pour créer un projet d’application console dans Visual C# :
- Démarrez Microsoft Visual Studio .NET ou Visual Studio.
- On the File menu, point to New, and then click Project.
- Cliquez sur Projets Visual C# sous Types de projets, puis sur Application console sous Modèles.
- Dans la zone Nom , tapez ConsoleEnum.
Renommez Class1.csen host.cs, puis remplacez le code dans host.cs par le code suivant :
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(); } } }
Dans le menu Projet , cliquez sur Ajouter une classe, puis tapez car dans la zone Nom .
Remplacez le code dans car.cs par le code suivant :
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
Dans le menu Projet , cliquez sur Ajouter une classe pour ajouter une autre classe au projet, puis tapez cars dans la zone Nom .
Remplacez le code dans cars.cs par le code suivant :
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];} } } }
Exécutez le projet.
La sortie suivante s’affiche dans la fenêtre console :
Ford 1992
Fiat 1988
Buick 1932
Ford 1932
Dodge 1999
Honda 1977
Meilleures pratiques
L’exemple de cet article est aussi simple que possible pour mieux expliquer l’utilisation de ces interfaces. Pour rendre le code plus robuste et s’assurer que le code utilise les bonnes pratiques actuelles, modifiez le code comme suit :
- Implémentez
IEnumerator
dans une classe imbriquée afin de pouvoir créer plusieurs énumérateurs. - Fournissez la gestion des exceptions pour la
Current
méthode deIEnumerator
. Si le contenu de la collection change, lareset
méthode est appelée. Par conséquent, l’énumérateur actuel est invalidé et vous recevez uneIndexOutOfRangeException
exception. D’autres circonstances peuvent également provoquer cette exception. Implémentez donc unTry...Catch
bloc pour intercepter cette exception et lever uneInvalidOperationException
exception.
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);
}
}
}
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour