Ich weiß, wie man die nicht generische IEnumerable wie folgt implementiert:
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();
}
}
}
Ich stelle jedoch auch fest, dass IEnumerable eine generische Version hat IEnumerable<T>
, aber ich kann nicht herausfinden, wie ich sie implementieren soll.
Wenn ich using System.Collections.Generic;
meine using-Direktiven hinzufüge und dann ändere:
class MyObjects : IEnumerable
zu:
class MyObjects : IEnumerable<MyObject>
Klicken Sie dann mit der rechten Maustaste auf IEnumerable<MyObject>
und wählen Sie Implement Interface => Implement Interface
, Visual Studio fügt den folgenden Codeblock hilfreich hinzu:
IEnumerator<MyObject> IEnumerable<MyObject>.GetEnumerator()
{
throw new NotImplementedException();
}
Das Zurückgeben des nicht generischen IEnumerable-Objekts aus der GetEnumerator();
Methode funktioniert diesmal nicht. Was soll ich hier einfügen ? Die CLI ignoriert jetzt die nicht generische Implementierung und geht direkt zur generischen Version, wenn sie versucht, während der foreach-Schleife durch mein Array aufzulisten.
this.GetEnumerator()
und der einfachen RückgabeGetEnumerator()
?Collection<MyObject>
und müssen dann keinen benutzerdefinierten Code schreiben.List<T>
und implementierenIEnumerable<T>
.Sie möchten wahrscheinlich keine explizite Implementierung von
IEnumerable<T>
(was Sie gezeigt haben).Das übliche Muster ist die Verwendung von
IEnumerable<T>
'sGetEnumerator
bei der expliziten Implementierung vonIEnumerable
:quelle
IEnumerable
ist jedoch redundant (IEnumerable<T>
erbt bereits davon).Warum machst du das manuell?
yield return
automatisiert den gesamten Prozess der Handhabung von Iteratoren. (Ich habe auch in meinem Blog darüber geschrieben , einschließlich eines Blicks auf den vom Compiler generierten Code).Wenn Sie es wirklich selbst tun möchten, müssen Sie auch einen generischen Enumerator zurückgeben. Sie können
ArrayList
kein mehr verwenden, da dies nicht generisch ist. Ändern Sie esList<MyObject>
stattdessen in a. Dies setzt natürlich voraus, dassMyObject
Ihre Sammlung nur Objekte vom Typ (oder abgeleitete Typen) enthält.quelle
yield return
. Ich habe fälschlicherweise angenommen, dass es eine benutzerdefinierte Verarbeitung gibt.Wenn Sie mit Generika arbeiten, verwenden Sie List anstelle von ArrayList. Die Liste enthält genau die GetEnumerator-Methode, die Sie benötigen.
quelle
Mylist zu einer machen
List<MyObject>
, ist eine Optionquelle
Beachten Sie, dass der
IEnumerable<T>
bereits implementierteSystem.Collections
Ansatz darin besteht, IhreMyObjects
KlasseSystem.Collections
als Basisklasse abzuleiten ( Dokumentation ):Wir können später unsere eigene Implemenation machen die virtuellen außer Kraft zu setzen
System.Collections
Methoden individuelle Verhalten , um (nur fürClearItems
,InsertItem
,RemoveItem
, undSetItem
zusammen mitEquals
,GetHashCode
undToString
abObject
). Im Gegensatz zu dem,List<T>
der nicht leicht erweiterbar ist.Beispiel:
Bitte beachten Sie, dass das Fahren von
collection
empfohlen nur dann empfohlen wird, wenn ein benutzerdefiniertes Erfassungsverhalten erforderlich ist, was selten vorkommt. siehe Verwendung .quelle