foreachループはインターフェイスIEnumerator
を使用しIEnumerable
、カスタムタイプ(クラス)のオブジェクトを反復するためだけに使用しますか、それとも組み込みタイプ(舞台裏)を反復するためにも使用しますか?
4 に答える
Foreach 自体は依存しませんIEnumerable
。ただし、型がそれを実装している場合、foreach ループはそれを列挙できます (パターンベースのマッチング)。
舞台裏ではGetEnumerator()
メソッドのみが必要で、列挙子には and が含まれている必要がCurrent
ありMoveNext()
ます。
MSDN から:
コレクションの種類:
- 次のいずれかのタイプである必要があります: interface、class、またはstruct。
- たとえば、型を返すGetEnumeratorという名前のインスタンス メソッドを含める必要があります
Enumerator
(以下で説明します)。型
Enumerator
(クラスまたは構造体) には以下が含まれている必要があります。
- 返すCurrentという名前のプロパティ
ItemType
、またはそれに変換できる型。プロパティ アクセサーは、コレクションの現在の要素を返します。- MoveNextという名前のboolメソッド。アイテム カウンターをインクリメントし、コレクション内にさらにアイテムがある場合はtrueを返します。
MSDNから- コレクションでの foreach の使用
UPDATED : これについては、更新された MSDN ページを参照してください - How to: Access a Collection Class with foreach (C# Programming Guide)。
列挙子を定義します。IEnumerable 宣言はありません。
public class WorkInfoEnumerator
{
List<WorkItem > wilist= null;
int currentIndex = -1;
public MyClassEnumerator(List<WorkItem > list)
{
wilist= list;
}
public WorkItem Current
{
get
{
return wilist[currentIndex];
}
}
public bool MoveNext()
{
++currentIndex;
if (currentIndex < wilist.Count)
return true;
return false;
}
}
public class WorkInfo
{
List<WorkItem > mydata = new List<WorkItem >();
public WorkInfoEnumerator GetEnumerator()
{
return new WorkInfoEnumerator(mydata);
}
}
コードのどこかで使用できます:
WorkInfo wi = new WorkInfo();
foreach(WorkItem witem in wi)
{
}
foreach は、ネイティブ型とカスタム型の両方に IEnumerable を使用します。たとえば、すべての配列型のベースである System.Array を見ると、IEnumerable が実装されています。
for-each は言語構造であり、カスタム型と組み込み型を実際には区別しません。
for each は に依存せずIEnumerable
、パターン ベースのマッチングを使用します。http://blogs.msdn.com/b/ericlippert/archive/2011/06/30/following-the-pattern.aspxを参照してください。