【C#】IEnumerableについて

度々躓きの原因になっている印象のある"IEnumerable"についてまとめたいと思います。

IEnumerableとは?

ものすごく簡単に言うと、「配列やCollectionなど、『複数のものを内包するインスタンス』に共通の動作を付与するためのインターフェース」です。

インターフェースとは?

別の記事手取り扱う予定ですので、現時点では「具体的な中身がわからなくても、特定のメソッドは持っていることを確約する仕組み」と思って下さい。

大まかな使い方について

上記の通り、『複数のものを内包するインスタンス』に共通の動作を付与する、ということですが、これがどういうことかと言うと、

  • 昔ながらの「配列」であっても、可変長配列である「List」であっても、DataRowCollectionなど、他者が作った「何かを寄せ集めたもの」であっても、中身に囚われずに同じように処理を実施する

ためのものです。
常に「昔ながらの配列」を相手にするときにしか呼ばれないメソッドであれば「配列」に対する処理だけすればいいのですが、ListやCollectionなども相手にする必要がある場合などは代わりに「IEnumerable」を相手にする処理を書くことで汎用性が高まります。
一方、特定の相手にしかない情報を使う(Listにはあるが配列にはないメソッドなど)を使いたいのであればこれは成り立ちません。
あくまで「汎用化」であるという認識です。

具体的な仕組みについて

IEnumerableには型を指定しないもの(System.Collections.IEnumerable)と、
(ジェネリック(別項目)で)型を指定するもの(System.Collections.Generic.IEnumerable<out T>)があります。

System.Collections.IEnumerable(型を指定しない)の場合

・IEnumerator GetEnumerator()
 というメソッドを必ず実装しています。
これは「foreach」などで繰り返し処理をする場合に、個別の内容を取ってくる方法を指定するものです。
型情報がないため、foreachの中などで個別の項目を見る場合にはobject扱いとなります

System.Collections.Generic.IEnumerable<out T>(型を指定する)の場合

・IEnumerator IEnumerable.GetEnumerator()
・IEnumerator<T> GetEnumerator()
 というメソッドを必ず実装しています。
1つ目の「IEnumerator IEnumerable.GetEnumerator()」は型を指定しない場合のものと同一です。
型を指定する必要があるため、戻り値の型指定が加わった2つ目の「IEnumerator<T> GetEnumerator()」が主に使われることになります。
型指定の部分以外は、「foreach」などで繰り返し処理をする場合に、個別の内容を取ってくる方法を指定するものという意味で大きな違いはありません。

自分で書くコードで使う必要はある?

上記の通り、あくまで「汎用化」目的になるため、必ずしも使用する必要はありません。
ただ、組込みのメソッドなどで引数や戻り値にしばしば使われているため、どういったものが「IEnumerable」なのか、は意識しておく方が無駄な変換を減らせる可能性があります。
「配列」も「List」も、であるため、可変長引数(params object[] argsのargs)をそのまま代入することも可能です。
また、自作クラスでforeachで取り回したい時などは実装する必要があったりもします。少なくとも知っていて損はないですね。

IEnumerableを実装死しているインスタンスの取り回しについては「LINQ」という拡張メソッドを使用すると色々楽ができます。
これも今後取りまとめる予定です。

結論

IEnumerableとは

  • 昔ながらの「配列」であっても、可変長配列である「List」であっても、Collectionなど「何かを寄せ集めたもの」であっても、中身に囚われずに同じように処理を実施するための汎用的対象である

  • IEnmerableを知っているとコードを記載する上で楽になる部分がある

といったところかと思います。
他の領域とも絡むものが多いので、今回触れなかった部分はまたいずれ…


この記事が気に入ったらサポートをしてみませんか?