今回の記事ではコレクションに関係するIEnumearble
とIEnumerator
について解説していきます。
IEnumerable
およびIEnumerator
はコレクションの要素を取り出す操作を一般化したものになります。少し理解しづらいかもしれませんが、便利なものなので是非マスターしてください。
コレクションの関連記事:
また、UnityではコルーチンというIEnumerator
を返すメソッドがあります。こちらも便利なUnityの機能になりますので使えるようになると便利です。
foreach文に関係するIEnumerable・IEnumeratorとは

コレクションからIEnumerableまたはIEnumeratorを作成し、IEnumeartorを経由して要素にアクセスする。
IEnumerable
とIEnumerator
はどちらもコレクションの要素を一つづつ参照していくためのインターフェースになります。
コレクションの要素を見る時はループ処理を利用しますが、実はこれらのインターフェースが提供しているメンバだけで十分にコレクションの要素をループさせることができます。
初めて使う方から見るとわかりづらいかもしれませんが、先人達の経験に習う感じで使ってみてください。
- IEnumerator:コレクションから取得できる。取得したコレクションの要素を一つづつ参照する操作をまとめたインターフェース。
- IEnumerable:
IEnumerator
を作成するためのインターフェース。Linq操作に対応しており、直接IEnumerator
を使用するよりこちらを使用した方が便利。
これらインターフェースにはテンプレート機能を利用したものとそうではないものが存在しています。各々の名前空間は次のものになります。
System.Collections
:テンプレートなしの方System.Collections.Generic
:テンプレート有りの方
テンプレートなしの方では値はobject型として扱われますので、使用する時は型変換を行ってください。
C#ではコレクション型はIEnumerableインターフェースを継承していますので、IEnumerable.GetEnumeratorメソッドでコレクションに対応するIEnumeratorを取得できます。
foreach文を使わずにループさせてみよう!

IEnumeratorインターフェースのメンバだけでコレクションの要素をループしていくことができる。
それではforeach文を使わずにループさせてみましょう!
現在では通常は必要になる機会はないですが、昔のコードなどforeach文がまだない時に作られたクラスではここのサンプルコードのようなやり方でループさせる必要があったんです。
Unityのクラスでもたまにそんなクラスがあるので豆知識として覚えておくと便利です。
foreach文を使わずにループする時はIEnumeratorを直接使用します。
IEnumerableの場合はGetEnumeratorメソッドを使用してIEnumeratorを取得してください。
IEnumeratorには次のメンバがあり、これらのメンバだけでコレクションの要素をループさせられます。
- Currentプロパティ:現在の要素
- MoveNextメソッド:次の要素に移動する。全ての要素に移動後、移動できなかった場合はfalseを戻り値として返します。
- Resetメソッド:IEnumeratorを最初の状態に戻す。
IEnumerable・IEnumeratorを作ってみよう!
IEnumerable
・IEnumeartor
はインターフェースなのでそれらを継承するクラスを定義することもできます。
IEnumeratorを定義する書き方
次のサンプルコードではリスト型をコンストラクタから受け取り、そのリストの要素を全て見ていくIEnumerable
とIEnumerator
を定義しています。
これらを使う時は
using System.Collections
を宣言するのを忘れないようにしましょう。
リストにはこれと同じものを既に定義しているのであまり意味はないクラスになりますが、書き方の参考としてください。
IEnumeratorを定義しない書き方
また毎回IEnumeratorを継承して定義するのは大変なので、yieldキーワードを使用し次のように省略することもできます。
こちらのサンプルではIEnumerable.GetEnumeratorメソッド内でIEnumerator型を直接返すのではなくyieldキーワードを使用して戻り値を返しています。
IEnumeratorを戻り値に持つメソッドは上のように書くこともでき、途中でメソッドを中断できます。
yield return
と書くとメソッドはその場所で中断します。処理を再開したい時はIEnumerator.MoveNextメソッドを呼び出してください。
yield
キーワードの詳しい書き方については次のコルーチンを見てください。
コルーチンについて

UnityではIEnumeratorを戻り値とするメソッドをコルーチンとして扱うことができる。
Unityではコルーチン(Coroutine)というメソッドの処理を一時中断させる機能があります。戻り値にIEnumeratorを返すメソッドをコルーチンとして使用できます。
コルーチンの定義の仕方

yieldキーワードはIEnumeratorを戻り値に持つメソッドで使用できる。returnの前に書き、書いた場所でメソッドの処理を中断することができる。
IEnumeratorを戻り値に持つメソッドの場合は戻り値の前に必ずyieldキーワードを先に付けてください。
- yieldキーワードの書き方:
yield return <戻り値>
また、メソッドの途中で処理を終了させたい場合はbreakキーワードを次のように書いてください。
- メソッドを終了させたい時:
yield break;
Unityではコルーチンが返す戻り値として使えるクラスがいくつか用意されています。それらのクラスを使用することで、コルーチンが中断した際にどのタイミングで処理を再開するかを指定することができます。
以下のクラスは全てUnityEngine.YieldInstructionクラスから派生しています。
-
WaitForEndOfFrame
-
WaitForFixedUpdate
-
WaitForSeconds
-
WaitForSecondsRealtime
-
WaitUntil
-
WaitWhile
また、nullを返すと次のフレームまで処理の実行を中断することができます。
コルーチンの使い方
コルーチンを定義しましたら、MonoBehaviour.StartCoroutine
メソッドで実行しましょう!
StartCoroutine
メソッドは引数にIEnumerator
を受け取り、問題なければUnityEngine.Coroutine
型を戻り値として返します。
- コルーチンの実行:Coroutine c = MonoBehaviour.StartCoroutine(<コルーチンの戻り値を渡す>);
このCoroutine型は実行したコルーチンを表すものになり、次のメソッドで使用されます。
MonoBehaviour.StopCoroutine
メソッド:実行中のコルーチンを終了させる。
IEnumeratorを返すStartメソッドについて
MonoBehaviour.Start
メソッドの戻り値にはvoid
ではなくIEnumerator
を指定することができます。
このように書くとStartメソッド自体がコルーチンとして実行されますので、豆知識として覚えておくと便利です。
【実践】コルーチンを作ってみよう!
それでは実際にコルーチンを使ってみましょう!
本サイトではこちらの記事でもコルーチンを使用しているので参考にしてみてください。
ここでのサンプルコードではGameObjectを一定間隔でワープさせるものになります。

サンプルを実行するとGameObjectが一定時間ごとに左右にワープするようになる。クリックするとワープを止める。
一定間隔待つのにWaitForSecondsクラスを利用しています。コルーチン内でそのクラスをyieldキーワードを使用して戻り値として返しているのに注目してください。
また、GameObjectをクリックしたらワープを停止するようにしています。OnMouseUpAsButtonメソッドの中でStopCoroutineを呼び出している部分がコルーチンを停止させている処理になります。
一応、nullを渡すと例外が発生するのでnullチェックを行っています。また、コルーチンの実行が終わった場合でもCoroutine側には何も影響を与えないため、終了タイミングでnullを設定している部分にも注目してください。
まとめ
今回の記事ではIEnumerable
・IEnumerator
とUnityのコルーチン
について解説してきました。簡単にまとめると以下のようになります。
- IEnumeratorはコレクションの要素を探索するときに使用する。
- IEnumerableはIEnumeratorを作るクラスのこと。
- IEnumeratorは直接使用するのではなくIEnumerableを経由して使用する方が便利。
- IEnumerableを利用するときはLinqという必要な要素だけ取り出す機能が利用できる。
- UnityのコルーチンではIEnumeratorを返すメソッドが使われる。
- IEnumeratorを返すメソッドにはyieldキーワードを付けた戻り値を返す必要がある。
それでは次の記事に行ってみましょう!

コメント