この記事では主に C# の IEnumerable および IEnumerator インターフェイスに関する関連知識を紹介します。これは、エディターで見てみましょう
古いものを振り返り、新しいものを学ぶことができます。時間があるときに何度も復習してください。基礎知識が必要であり、理解と記憶が深まります。
Foreach は、IEnumerable インターフェイスを実装するコレクションを反復処理したり、コンテナーを走査したりするためによく使用されます。公式の説明によれば、IEnumerable は列挙型インターフェイスであり、IEnumerator は反復子インターフェイスです。文字通り、意味はそれほど変わりません。一つずつ分析してみましょう。
IEnumerable インターフェイス
public interface IEnumerable { IEnumerator GetEnumerator(); }
IEnumerator インターフェース
public interface IEnumerator { object Current { get; } bool MoveNext(); void Reset(); }IEnumerator インターフェースには 3 つの要素があり、1 つは現在のコレクション内の要素を返す
attributeCurrent メソッドです。これは、メソッド MoveNext() のトラバーサルはすべて後方トラバーサルではないでしょうか。 Reset()は文字通りリセットという意味なのでわかりやすいですね。仮説を立ててください: IEnumerable インターフェイスは IEnumerator インターフェイス イテレータを返すため、カスタム コンテナは IEnumerator イテレータ インターフェイスを継承するだけで実装できますか?
Phone クラスを定義しますpublic class Phone
{
public string Name;
public Phone(string name)
{
this.Name = name;
}
}
という名前のイテレーターを定義し、そのインターフェイス IEnumeratorpublic 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);
}
}
を実装します 結果は次のようになります:
予想どおり、実際に機能するのは IEnumerator ですインターフェース、カスタム コンテナーをループすることはできますが、本来の目的はループ アクセスとトラバーサルに Foreach を使用することでした。そうですね、それを行うには IEnumerable インターフェイスを表示するだけです。 Phone クラスを少し変更します:
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(); }
結果は次のようになります:
これで、汎用コンテナー
PhonePackage に展開し、汎用の 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;
}
}
}
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);
}
結果は次のようになります:
IEnumerator イテレータ インターフェイスは非常に冗長であり、yield はトラバーサルを簡素化する単なる構文糖です。
以上がC# IEnumerable および IEnumerator インターフェイスの簡単な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。