Heim  >  Artikel  >  Backend-Entwicklung  >  Eine kurze Einführung in die C#-Schnittstellen IEnumerable und IEnumerator

Eine kurze Einführung in die C#-Schnittstellen IEnumerable und IEnumerator

黄舟
黄舟Original
2017-03-21 11:22:485316Durchsuche

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-Schnittstelle

public interface IEnumerable
{ 
 IEnumerator GetEnumerator();
}
Klassen, die die

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-Schnittstelle

IEnumerator-Schnittstelle hat drei Dinge, ein
public interface IEnumerator
{ 
 object Current { get; }
 bool MoveNext(); 
 void Reset();
}
Attribut

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-Klasse

Definieren Sie einen Iterator mit dem Namen
public class Phone 
{
 public string Name;
 public Phone(string name)
 {
  this.Name = name;
 }
}
MyEnumerator

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;
 }
}
Das Ergebnis zeigt:
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);
 }
 }
Das Ergebnis zeigt:
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 IEnumerable8742468051c85b06f0a0af9e3e506b5c

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;
  }
 }
 }
Das Ergebnis zeigt:
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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn