Dieser Artikel stellt hauptsächlich die relevanten Kenntnisse der IEnumerable- und IEnumerator-Schnittstellen in C# vor, die einen sehr guten Referenzwert haben. Schauen wir uns das mit dem Editor an Die Vergangenheit und das Neue lernen. Wenn Sie Zeit haben, ist es notwendig, Ihr Grundwissen regelmäßig zu wiederholen, und es kann Ihr Verständnis und Ihr Gedächtnis vertiefen.
Foreach wird oft verwendet, um Sammlungen zu durchlaufen und Container zu durchlaufen, die die IEnumerable-Schnittstelle implementieren. Ich bin manchmal etwas verwirrt über die IEnumerable- und IEnumerator-Schnittstellen. Laut der offiziellen Erklärung ist IEnumerable eine Enumerator-Schnittstelle ist ein Iterator. Die Schnittstellen unterscheiden sich nicht wesentlich von der wörtlichen Bedeutung.
IEnumerable-Schnittstellepublic interface IEnumerable { IEnumerator GetEnumerator(); }
IEnumerable-Schnittstelle erben, müssen die verfügbar gemachte GetEnumerator()-Methode implementieren und ein IEnumerator-Schnittstellenobjekt zurückgeben , es scheint, dass der echte IEnumerator F12 ist, um zu sehen, was zum Teufel in IEnumerator steckt.
IEnumerator-SchnittstelleIEnumerator-Schnittstelle hat drei Dinge, ein
public interface IEnumerator { object Current { get; } bool MoveNext(); void Reset(); }
Aktuell, gibt die Elemente in der aktuellen Sammlung zurück, die Methode MoveNext ( ), um zum nächsten zu gelangen, bedeutet „Reset()“ nicht wörtlich „Zurücksetzen“. Stellen Sie eine Hypothese auf: Da die IEnumerable-Schnittstelle einen IEnumerator-Schnittstellen-Iterator zurückgibt, kann ein benutzerdefinierter Container implementiert werden, indem nur die IEnumerator-Iterator-Schnittstelle geerbt wird? Definieren Sie eine
Phone-KlasseDefinieren Sie einen Iterator mit dem Namen
public class Phone { public string Name; public Phone(string name) { this.Name = name; } }
und implementieren Sie dessen Schnittstelle IEnumerator
public class MyEnumerator : IEnumerator { Phone[] p; int idx = -1; public MyEnumerator(Phone[] t) { p = t; } public object Current { get { if (idx == -1) return new IndexOutOfRangeException(); return p[idx]; } } public bool MoveNext() { idx++; return p.Length > idx; } public void Reset() { idx = -1; } }
class Program { static void Main(string[] args) { show("-----------IEnumerator------------"); Phone[] phones = new Phone[] { new Phone("iPhone 7s"), new Phone("iPhone 6s"), new Phone("iPhone 5s") }; MyEnumerator enumerator = new MyEnumerator(phones); while (enumerator.MoveNext()) { Phone p = enumerator.Current as Phone; show(p.Name); } Console.ReadKey(); } static void show(string i) { Console.WriteLine(i); } }
Was wirklich die Arbeit erledigt, ist wie erwartet die IEnumerator-Schnittstelle, die den benutzerdefinierten A-Container durchlaufen kann. Die ursprüngliche Absicht besteht jedoch darin, Foreach für den Schleifenzugriff und das Durchlaufen zu verwenden. Dann können wir dazu nur die IEnumerable-Schnittstelle anzeigen. Ändern Sie die Telefonklasse leicht:
public class Phone : IEnumerable { public string Name ; public Phone(string name) { this.Name = name; } Phone[] p; public Phone(Phone[] t) { p = t; } public IEnumerator GetEnumerator() { return new MyEnumerator(p); } }
static void Main(string[] args) { show("-----------IEnumerator------------"); Phone[] phones = new Phone[] { new Phone("iPhone 7s"), new Phone("iPhone 6s"), new Phone("iPhone 5s") }; MyEnumerator enumerator = new MyEnumerator(phones); while (enumerator.MoveNext()) { Phone p = enumerator.Current as Phone; show(p.Name); } show("-----------IEnumerable------------"); Phone phoneList = new Phone(phones); foreach (Phone p in phoneList) { show(p.Name); } Console.ReadKey(); }
Es ist fertig und erweitert es dann in einen universellen Container
PhonePackage, erben Sie einfach die generische IEnumerable
public class PhonePackage<T> : IEnumerable<T> { private List<T> dataList = null; public void Add(T t) { if (dataList == null) dataList = new List<T>(); dataList.Add(t); } public IEnumerator<T> GetEnumerator() { foreach (T t in dataList) { yield return t; } } IEnumerator IEnumerable.GetEnumerator() { foreach (T t in dataList) { yield return t; } } }
static void Main(string[] args) { show("-----------IEnumerator------------"); Phone[] phones = new Phone[] { new Phone("iPhone 7s"), new Phone("iPhone 6s"), new Phone("iPhone 5s") }; MyEnumerator enumerator = new MyEnumerator(phones); while (enumerator.MoveNext()) { Phone p = enumerator.Current as Phone; show(p.Name); } show("-----------IEnumerable------------"); Phone phoneList = new Phone(phones); foreach (Phone p in phoneList) { show(p.Name); } show("-----------IEnumerable<T>------------"); PhonePackage<Phone> phonePackage = new PhonePackage<Phone>(); phonePackage.Add(new Phone("iPhone 7s")); phonePackage.Add(new Phone("iPhone 6s")); phonePackage.Add(new Phone("iPhone 5s")); foreach (Phone p in phonePackage) { show(p.Name); } Console.ReadKey(); } static void show(string i) { Console.WriteLine(i); }
Die IEnumerator-Iteratorschnittstelle ist ziemlich ausführlich und yield ist nur Syntaxzucker, der das Durchlaufen vereinfacht.
Das obige ist der detaillierte Inhalt vonEine kurze Einführung in die C#-Schnittstellen IEnumerable und IEnumerator. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!