IEnumerable.GetEnumerator メソッド
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
コレクションを反復処理する列挙子を返します。
public:
System::Collections::IEnumerator ^ GetEnumerator();
public System.Collections.IEnumerator GetEnumerator ();
abstract member GetEnumerator : unit -> System.Collections.IEnumerator
Public Function GetEnumerator () As IEnumerator
戻り値
コレクションを反復処理するために使用できる IEnumerator オブジェクト。
例
次のコード例は、カスタム コレクションのインターフェイスの IEnumerable 実装を示しています。 この例では、 GetEnumerator は明示的に呼び出されませんが、 (Visual Basic では)For Each
のforeach
使用をサポートするために実装されています。 このコード例は、 インターフェイスの大きな例の IEnumerable 一部です。
using System;
using System.Collections;
// Simple business object.
public class Person
{
public Person(string fName, string lName)
{
this.firstName = fName;
this.lastName = lName;
}
public string firstName;
public string lastName;
}
// Collection of Person objects. This class
// implements IEnumerable so that it can be used
// with ForEach syntax.
public class People : IEnumerable
{
private Person[] _people;
public People(Person[] pArray)
{
_people = new Person[pArray.Length];
for (int i = 0; i < pArray.Length; i++)
{
_people[i] = pArray[i];
}
}
// Implementation for the GetEnumerator method.
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator) GetEnumerator();
}
public PeopleEnum GetEnumerator()
{
return new PeopleEnum(_people);
}
}
// When you implement IEnumerable, you must also implement IEnumerator.
public class PeopleEnum : IEnumerator
{
public Person[] _people;
// Enumerators are positioned before the first element
// until the first MoveNext() call.
int position = -1;
public PeopleEnum(Person[] list)
{
_people = list;
}
public bool MoveNext()
{
position++;
return (position < _people.Length);
}
public void Reset()
{
position = -1;
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public Person Current
{
get
{
try
{
return _people[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}
class App
{
static void Main()
{
Person[] peopleArray = new Person[3]
{
new Person("John", "Smith"),
new Person("Jim", "Johnson"),
new Person("Sue", "Rabon"),
};
People peopleList = new People(peopleArray);
foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName);
}
}
/* This code produces output similar to the following:
*
* John Smith
* Jim Johnson
* Sue Rabon
*
*/
Imports System.Collections
' Simple business object.
Public Class Person
Public Sub New(ByVal fName As String, ByVal lName As String)
Me.firstName = fName
Me.lastName = lName
End Sub
Public firstName As String
Public lastName As String
End Class
' Collection of Person objects, which implements IEnumerable so that
' it can be used with ForEach syntax.
Public Class People
Implements IEnumerable
Private _people() As Person
Public Sub New(ByVal pArray() As Person)
_people = New Person(pArray.Length - 1) {}
Dim i As Integer
For i = 0 To pArray.Length - 1
_people(i) = pArray(i)
Next i
End Sub
' Implementation of GetEnumerator.
Public Function GetEnumerator() As IEnumerator _
Implements IEnumerable.GetEnumerator
Return New PeopleEnum(_people)
End Function
End Class
' When you implement IEnumerable, you must also implement IEnumerator.
Public Class PeopleEnum
Implements IEnumerator
Public _people() As Person
' Enumerators are positioned before the first element
' until the first MoveNext() call.
Dim position As Integer = -1
Public Sub New(ByVal list() As Person)
_people = list
End Sub
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
position = position + 1
Return (position < _people.Length)
End Function
Public Sub Reset() Implements IEnumerator.Reset
position = -1
End Sub
Public ReadOnly Property Current() As Object Implements IEnumerator.Current
Get
Try
Return _people(position)
Catch ex As IndexOutOfRangeException
Throw New InvalidOperationException()
End Try
End Get
End Property
End Class
Class App
Shared Sub Main()
Dim peopleArray() As Person = { _
New Person("John", "Smith"), _
New Person("Jim", "Johnson"), _
New Person("Sue", "Rabon")}
Dim peopleList As New People(peopleArray)
Dim p As Person
For Each p In peopleList
Console.WriteLine(p.firstName + " " + p.lastName)
Next
End Sub
End Class
' This code produces output similar to the following:
'
' John Smith
' Jim Johnson
' Sue Rabon
注釈
C# 言語の foreach
ステートメント (Visual Basic の場合は For Each
) を使用することで列挙子の複雑さを回避できます。 したがって、列挙子を直接操作するのではなく、foreach
を使用することをお勧めします。
列挙子を使用すると、コレクション内のデータを読み取ることができますが、基になるコレクションを変更することはできません。
最初、列挙子はコレクションの先頭の要素の前に位置付けられます。 Reset メソッドは、この位置に列挙子を戻します。 この位置では、Current プロパティは定義されていません。 そのため、Current の値を読み取る前に、MoveNext メソッドを呼び出し、列挙子をコレクションの最初の要素に進める必要があります。
Current は、MoveNext または Reset が呼び出されるまでは同じオブジェクトを返します。 MoveNext は、Current を次の要素に進めます。
MoveNext がコレクションの末尾を通過した場合、列挙子がコレクション内の最後の要素の後に配置され、MoveNext は false
を返します。 列挙子がこの位置にある場合、後続の MoveNext 呼び出しも false
を返します。 最後の MoveNext 呼び出しが false
を返す場合、Current は定義されていません。 コレクションの先頭の要素に再び Current を設定するには、先に Reset を呼び出してから MoveNext を呼び出します。
要素の追加、変更、削除など、コレクションに変更が加えられた場合、列挙子の動作は未定義です。
列挙子はコレクションに排他アクセスできないため、コレクションの列挙処理は本質的にスレッド セーフな処理ではありません。 列挙処理でスレッド セーフを確保するには、列挙処理が終わるまでコレクションをロックできます。 コレクションに対し複数のスレッドがアクセスして読み取りや書き込みを行うことができるようにするには、独自に同期化を実装する必要があります。
適用対象
こちらもご覧ください
.NET