イテレータ以前にIEnumerator [C#]

イテレータを調べていると、それ以前にIEnumeratorやIEnumerableをあまり理解してなかったので、また横道にそれて、まずこちらを調べることに。

まあ、簡単に解釈すると「要素を一つ一つ順番に取り出していくことが出来る」と言うことで、配列的なものを想像すればイイんじゃないかな。
アバウトすぎるとも思わないのだが。

msdnのヘルプでは

...コレクションを反復処理する列挙子を返します。
だそうで。


実際に書いてみる

単純な配列なら
int[] ia = new int[] { 1, 2, 3 };
IEnumerator iae = ia.GetEnumerator();
『IEnumerator』使うなら『using System.Collections;』が必要。


ジェネリックなListクラスならこんなのとか
List<int> i = new List<int>() { 1, 2, 3 };
IEnumerator<int> ie = i.GetEnumerator();


こんな感じでIEnumerator型にしちゃって以下のように使う。
using (IEnumerator<int> ie = i.GetEnumerator())
{
    while (ie.MoveNext())
    {
        Console.WriteLine(ie.Current);
    }
}
こんな感じで使えばヨロシ。

ちなみに最初の Current には何も入っていない。厳密には『未定義』。MoveNext() して最初の要素が返る。じゃないとWhile文の条件に入るといきなり MoveNext なんてつじつまが合いません。

上では using を使ってちゃんとDisposeするように書いたんですけど、try ... finally だとなぜかDisposeしてくれないんですけどナニユエ?
多分、using 使うこと自体無意味...


ついでにListBox.Itemsについて

ListBoxのItemsにはなんで GetRange メソッドがないんですかねぇ。
簡単に項目を取得する方法はないかちょっと調べてみた。

ListBoxのItemsをmsdnで見ると
public class ObjectCollection : IList, ICollection, IEnumerable
...
ListBox.ObjectCollection クラスは、ListBox に表示される項目を格納します。
はい、そうですか。つまりこういうことですか。
IList il = listBox1.Items;
IEnumerable iebl = listBox1.Items;
ICollection ic = listBox1.Items;

IEnumerableということは
IEnumerator ier = listBox1.Items.GetEnumerator();

string str = "";
while (ier.MoveNext())
{
    str += ier.Current + "\n";
}
return str;
こんなことができるわけですね。

速度求めるならこんなことしないでfor文で取得した方が速いんですけど、汎用性的な観点で必要な場面ってのが出てくるんでしょうかねぇ。

0 Comments:

Sony Style(ソニースタイル)
デル株式会社

Recent Posts