Je sais comment implémenter le IEnumerable non générique, comme ceci:
using System;
using System.Collections;
namespace ConsoleApplication33
{
class Program
{
static void Main(string[] args)
{
MyObjects myObjects = new MyObjects();
myObjects[0] = new MyObject() { Foo = "Hello", Bar = 1 };
myObjects[1] = new MyObject() { Foo = "World", Bar = 2 };
foreach (MyObject x in myObjects)
{
Console.WriteLine(x.Foo);
Console.WriteLine(x.Bar);
}
Console.ReadLine();
}
}
class MyObject
{
public string Foo { get; set; }
public int Bar { get; set; }
}
class MyObjects : IEnumerable
{
ArrayList mylist = new ArrayList();
public MyObject this[int index]
{
get { return (MyObject)mylist[index]; }
set { mylist.Insert(index, value); }
}
IEnumerator IEnumerable.GetEnumerator()
{
return mylist.GetEnumerator();
}
}
}
Cependant, je remarque également que IEnumerable a une version générique IEnumerable<T>
, mais je ne peux pas comprendre comment l'implémenter.
Si j'ajoute using System.Collections.Generic;
à mes directives d'utilisation, puis que je change:
class MyObjects : IEnumerable
à:
class MyObjects : IEnumerable<MyObject>
Et puis faites un clic droit sur IEnumerable<MyObject>
et sélectionnez Implement Interface => Implement Interface
, Visual Studio ajoute utilement le bloc de code suivant:
IEnumerator<MyObject> IEnumerable<MyObject>.GetEnumerator()
{
throw new NotImplementedException();
}
Le retour de l'objet IEnumerable non générique à partir de la GetEnumerator();
méthode ne fonctionne pas cette fois, alors que dois-je mettre ici? La CLI ignore maintenant l'implémentation non générique et se dirige directement vers la version générique lorsqu'elle essaie d'énumérer via mon tableau pendant la boucle foreach.
this.GetEnumerator()
et le simple retourGetEnumerator()
?Collection<MyObject>
et vous n'aurez pas à écrire de code personnalisé.List<T>
et implémenterIEnumerable<T>
comme indiqué dans votre réponse.Vous ne voulez probablement pas une implémentation explicite de
IEnumerable<T>
(ce que vous avez montré).Le modèle habituel est d'utiliser
IEnumerable<T>
desGetEnumerator
dans l'implémentation explicite deIEnumerable
:la source
IEnumerable
est redondante (enIEnumerable<T>
hérite déjà).Pourquoi le faites-vous manuellement?
yield return
automatise l'ensemble du processus de gestion des itérateurs. (J'ai également écrit à ce sujet sur mon blog , y compris un aperçu du code généré par le compilateur).Si vous voulez vraiment le faire vous-même, vous devez également renvoyer un énumérateur générique. Vous ne pourrez plus en utiliser
ArrayList
car ce n'est pas générique. Changez-le à laList<MyObject>
place. Cela suppose bien sûr que vous n'avez que des objets de typeMyObject
(ou des types dérivés) dans votre collection.la source
yield return
. J'ai supposé à tort qu'il y avait un traitement personnalisé.Si vous travaillez avec des génériques, utilisez List au lieu de ArrayList. La liste a exactement la méthode GetEnumerator dont vous avez besoin.
la source
faire mylist en a
List<MyObject>
, est une optionla source
Notez que le
IEnumerable<T>
déjà implémenté par leSystem.Collections
donc une autre approche est de dériver votreMyObjects
classeSystem.Collections
comme classe de base ( documentation ):Nous pouvons faire plus tard notre propre implemenation de passer outre les virtuels
System.Collections
méthodes pour fournir un comportement personnalisé (uniquement pourClearItems
,InsertItem
,RemoveItem
etSetItem
ainsiEquals
,GetHashCode
etToString
deObject
). Contrairement auList<T>
qui n'est pas conçu pour être facilement extensible.Exemple:
Veuillez noter que la conduite à partir de
collection
recommandé uniquement dans le cas où un comportement de collecte personnalisé est nécessaire, ce qui se produit rarement. voir l' utilisation .la source