IOrderedDictionary.GetEnumerator Метод
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Возвращает перечислитель, выполняющий итерацию элементов коллекции IOrderedDictionary.
public:
System::Collections::IDictionaryEnumerator ^ GetEnumerator();
public System.Collections.IDictionaryEnumerator GetEnumerator ();
abstract member GetEnumerator : unit -> System.Collections.IDictionaryEnumerator
Public Function GetEnumerator () As IDictionaryEnumerator
Возвращаемое значение
Объект IDictionaryEnumerator для всей коллекции IOrderedDictionary.
Реализации
Примеры
В следующем примере кода демонстрируется реализация простого IOrderedDictionary объекта на ArrayList основе класса . Реализованный IOrderedDictionary объект сохраняет имена в качестве ключей, а фамилии — в качестве значений, с добавленным требованием, чтобы каждое имя было уникальным. Этот код является частью более крупного примера кода, предоставленного IOrderedDictionary для класса .
public ref class PeopleEnum : IDictionaryEnumerator
{
private:
// Enumerators are positioned before the first element
// until the first MoveNext() call.
int position;
ArrayList^ _people;
public:
PeopleEnum(ArrayList^ list)
{
this->Reset();
_people = list;
}
virtual bool MoveNext()
{
position++;
return (position < _people->Count);
}
virtual void Reset()
{
position = -1;
}
virtual property Object^ Current
{
Object^ get()
{
try
{
return _people[position];
}
catch (IndexOutOfRangeException^)
{
throw gcnew InvalidOperationException();
}
}
}
virtual property DictionaryEntry Entry
{
DictionaryEntry get()
{
return (DictionaryEntry)(Current);
}
}
virtual property Object^ Key
{
Object^ get()
{
try
{
return ((DictionaryEntry^)_people[position])->Key;
}
catch (IndexOutOfRangeException^)
{
throw gcnew InvalidOperationException();
}
}
}
virtual property Object^ Value
{
Object^ get()
{
try
{
return ((DictionaryEntry^)_people[position])->Value;
}
catch (IndexOutOfRangeException^)
{
throw gcnew InvalidOperationException();
}
}
}
};
public ref class People : IOrderedDictionary
{
private:
ArrayList^ _people;
public:
People(int numItems)
{
_people = gcnew ArrayList(numItems);
}
int IndexOfKey(Object^ key)
{
for (int i = 0; i < _people->Count; i++)
{
if (((DictionaryEntry^)_people[i])->Key == key)
return i;
}
// key not found, return -1.
return -1;
}
virtual property Object^ default[Object^]
{
Object^ get(Object^ key)
{
return ((DictionaryEntry^)_people[IndexOfKey(key)])->Value;
}
void set(Object^ key, Object^ value)
{
_people[IndexOfKey(key)] = gcnew DictionaryEntry(key, value);
}
}
// IOrderedDictionary Members
virtual IDictionaryEnumerator^ GetEnumerator()
{
return gcnew PeopleEnum(_people);
}
virtual void Insert(int index, Object^ key, Object^ value)
{
if (IndexOfKey(key) != -1)
{
throw gcnew ArgumentException("An element with the same key already exists in the collection.");
}
_people->Insert(index, gcnew DictionaryEntry(key, value));
}
virtual void RemoveAt(int index)
{
_people->RemoveAt(index);
}
virtual property Object^ default[int]
{
Object^ get(int index)
{
return ((DictionaryEntry^)_people[index])->Value;
}
void set(int index, Object^ value)
{
Object^ key = ((DictionaryEntry^)_people[index])->Key;
_people[index] = gcnew DictionaryEntry(key, value);
}
}
// IDictionary Members
virtual void Add(Object^ key, Object^ value)
{
if (IndexOfKey(key) != -1)
{
throw gcnew ArgumentException("An element with the same key already exists in the collection.");
}
_people->Add(gcnew DictionaryEntry(key, value));
}
virtual void Clear()
{
_people->Clear();
}
virtual bool Contains(Object^ key)
{
if (IndexOfKey(key) == -1)
{
return false;
}
else
{
return true;
}
}
virtual property bool IsFixedSize
{
bool get()
{
return false;
}
}
virtual property bool IsReadOnly
{
bool get()
{
return false;
}
}
virtual property ICollection^ Keys
{
ICollection^ get()
{
ArrayList^ KeyCollection = gcnew ArrayList(_people->Count);
for (int i = 0; i < _people->Count; i++)
{
KeyCollection->Add( ((DictionaryEntry^)_people[i])->Key );
}
return KeyCollection;
}
}
virtual void Remove(Object^ key)
{
_people->RemoveAt(IndexOfKey(key));
}
virtual property ICollection^ Values
{
ICollection ^get()
{
ArrayList^ ValueCollection = gcnew ArrayList(_people->Count);
for (int i = 0; i < _people->Count; i++)
{
ValueCollection->Add( ((DictionaryEntry^)_people[i])->Value );
}
return ValueCollection;
}
}
// ICollection Members
virtual void CopyTo(Array^ array, int index)
{
_people->CopyTo(array, index);
}
virtual property int Count
{
int get()
{
return _people->Count;
}
}
virtual property bool IsSynchronized
{
bool get()
{
return _people->IsSynchronized;
}
}
virtual property Object^ SyncRoot
{
Object^ get()
{
return _people->SyncRoot;
}
}
// IEnumerable Members
virtual IEnumerator^ IfcGetEnumerator() = IEnumerable::GetEnumerator
{
return (IEnumerator^) gcnew PeopleEnum(_people);
}
};
public class People : IOrderedDictionary
{
private ArrayList _people;
public People(int numItems)
{
_people = new ArrayList(numItems);
}
public int IndexOfKey(object key)
{
for (int i = 0; i < _people.Count; i++)
{
if (((DictionaryEntry)_people[i]).Key == key)
return i;
}
// key not found, return -1.
return -1;
}
public object this[object key]
{
get
{
return ((DictionaryEntry)_people[IndexOfKey(key)]).Value;
}
set
{
_people[IndexOfKey(key)] = new DictionaryEntry(key, value);
}
}
// IOrderedDictionary Members
public IDictionaryEnumerator GetEnumerator()
{
return new PeopleEnum(_people);
}
public void Insert(int index, object key, object value)
{
if (IndexOfKey(key) != -1)
{
throw new ArgumentException("An element with the same key already exists in the collection.");
}
_people.Insert(index, new DictionaryEntry(key, value));
}
public void RemoveAt(int index)
{
_people.RemoveAt(index);
}
public object this[int index]
{
get
{
return ((DictionaryEntry)_people[index]).Value;
}
set
{
object key = ((DictionaryEntry)_people[index]).Key;
_people[index] = new DictionaryEntry(key, value);
}
}
// IDictionary Members
public void Add(object key, object value)
{
if (IndexOfKey(key) != -1)
{
throw new ArgumentException("An element with the same key already exists in the collection.");
}
_people.Add(new DictionaryEntry(key, value));
}
public void Clear()
{
_people.Clear();
}
public bool Contains(object key)
{
if (IndexOfKey(key) == -1)
{
return false;
}
else
{
return true;
}
}
public bool IsFixedSize
{
get
{
return false;
}
}
public bool IsReadOnly
{
get
{
return false;
}
}
public ICollection Keys
{
get
{
ArrayList KeyCollection = new ArrayList(_people.Count);
for (int i = 0; i < _people.Count; i++)
{
KeyCollection.Add( ((DictionaryEntry)_people[i]).Key );
}
return KeyCollection;
}
}
public void Remove(object key)
{
_people.RemoveAt(IndexOfKey(key));
}
public ICollection Values
{
get
{
ArrayList ValueCollection = new ArrayList(_people.Count);
for (int i = 0; i < _people.Count; i++)
{
ValueCollection.Add( ((DictionaryEntry)_people[i]).Value );
}
return ValueCollection;
}
}
// ICollection Members
public void CopyTo(Array array, int index)
{
_people.CopyTo(array, index);
}
public int Count
{
get
{
return _people.Count;
}
}
public bool IsSynchronized
{
get
{
return _people.IsSynchronized;
}
}
public object SyncRoot
{
get
{
return _people.SyncRoot;
}
}
// IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return new PeopleEnum(_people);
}
}
public class PeopleEnum : IDictionaryEnumerator
{
public ArrayList _people;
// Enumerators are positioned before the first element
// until the first MoveNext() call.
int position = -1;
public PeopleEnum(ArrayList list)
{
_people = list;
}
public bool MoveNext()
{
position++;
return (position < _people.Count);
}
public void Reset()
{
position = -1;
}
public object Current
{
get
{
try
{
return _people[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
public DictionaryEntry Entry
{
get
{
return (DictionaryEntry)Current;
}
}
public object Key
{
get
{
try
{
return ((DictionaryEntry)_people[position]).Key;
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
public object Value
{
get
{
try
{
return ((DictionaryEntry)_people[position]).Value;
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}
Public Class People
Implements IOrderedDictionary
Private _people As ArrayList
Public Sub New(ByVal numItems As Integer)
_people = New ArrayList(numItems)
End Sub
Public Function IndexOfKey(ByVal key As Object) As Integer
Dim i As Integer
For i = 0 To _people.Count - 1
If CType(_people(i), DictionaryEntry).Key = key Then
Return i
End If
Next i
' key not found, return -1.
Return -1
End Function
' IOrderedDictionary Members
Public Function GetEnumerator() As IDictionaryEnumerator _
Implements IOrderedDictionary.GetEnumerator
Return New PeopleEnum(_people)
End Function
Public Sub Insert(ByVal index As Integer, ByVal key As Object, _
ByVal value As Object) Implements IOrderedDictionary.Insert
If Not IndexOfKey(key) = -1 Then
Throw New ArgumentException("An element with the same key already exists in the collection.")
End If
_people.Insert(index, New DictionaryEntry(key, value))
End Sub
Public Sub RemoveAt(ByVal index As Integer) _
Implements IOrderedDictionary.RemoveAt
_people.RemoveAt(index)
End Sub
Public Property Item(ByVal index As Integer) As Object _
Implements IOrderedDictionary.Item
Get
Return CType(_people(index), DictionaryEntry).Value
End Get
Set(ByVal value As Object)
Dim key As Object = CType(_people(index), DictionaryEntry).Key
_people(index) = New DictionaryEntry(key, value)
End Set
End Property
' IDictionary Members
Public Function IDictionaryGetEnumerator() As IDictionaryEnumerator _
Implements IDictionary.GetEnumerator
Return New PeopleEnum(_people)
End Function
Public Property Item(ByVal key As Object) As Object _
Implements IDictionary.Item
Get
Return CType(_people(IndexOfKey(key)), DictionaryEntry).Value
End Get
Set(ByVal value)
_people(IndexOfKey(key)) = New DictionaryEntry(key, value)
End Set
End Property
Public Sub Add(ByVal key As Object, ByVal value As Object) _
Implements IDictionary.Add
If Not IndexOfKey(key) = -1 Then
Throw New ArgumentException("An element with the same key already exists in the collection.")
End If
_people.Add(New DictionaryEntry(key, value))
End Sub
Public Sub Clear() Implements IDictionary.Clear
_people.Clear()
End Sub
Public Function Contains(ByVal key As Object) As Boolean _
Implements IDictionary.Contains
If IndexOfKey(key) = -1 Then
Return False
Else
Return True
End If
End Function
Public ReadOnly Property IsFixedSize() As Boolean _
Implements IDictionary.IsFixedSize
Get
Return False
End Get
End Property
Public ReadOnly Property IsReadOnly() As Boolean _
Implements IDictionary.IsReadOnly
Get
Return False
End Get
End Property
Public ReadOnly Property Keys() As ICollection _
Implements IDictionary.Keys
Get
Dim KeyCollection As ArrayList = New ArrayList(_people.Count)
Dim i As Integer
For i = 0 To _people.Count - 1
KeyCollection.Add( CType(_people(i), DictionaryEntry).Key )
Next i
Return KeyCollection
End Get
End Property
Public Sub Remove(ByVal key As Object) _
Implements IDictionary.Remove
_people.RemoveAt(IndexOfKey(key))
End Sub
Public ReadOnly Property Values() As ICollection _
Implements IDictionary.Values
Get
Dim ValueCollection As ArrayList = New ArrayList(_people.Count)
Dim i As Integer
For i = 0 To _people.Count - 1
ValueCollection.Add( CType(_people(i), DictionaryEntry).Value )
Next i
Return ValueCollection
End Get
End Property
' ICollection Members
Public Sub CopyTo(ByVal array As Array, ByVal index As Integer) _
Implements ICollection.CopyTo
_people.CopyTo(Array, index)
End Sub
Public ReadOnly Property Count() As Integer _
Implements ICollection.Count
Get
Return _people.Count
End Get
End Property
Public ReadOnly Property IsSynchronized() As Boolean _
Implements ICollection.IsSynchronized
Get
Return _people.IsSynchronized
End Get
End Property
Public ReadOnly Property SyncRoot() As Object _
Implements ICollection.SyncRoot
Get
Return _people.SyncRoot
End Get
End Property
' IEnumerable Members
Public Function IEnumerableGetEnumerator() As IEnumerator _
Implements IEnumerable.GetEnumerator
Return New PeopleEnum(_people)
End Function
End Class
Public Class PeopleEnum
Implements IDictionaryEnumerator
Public _people As ArrayList
' Enumerators are positioned before the first element
' until the first MoveNext() call.
Dim position As Integer = -1
Public Sub New(ByVal list As ArrayList)
_people = list
End Sub
Public Function MoveNext() As Boolean _
Implements IEnumerator.MoveNext
position = position + 1
Return (position < _people.Count)
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 e As IndexOutOfRangeException
Throw New InvalidOperationException()
End Try
End Get
End Property
Public ReadOnly Property Entry() As DictionaryEntry _
Implements IDictionaryEnumerator.Entry
Get
Return CType(Current, DictionaryEntry)
End Get
End Property
Public ReadOnly Property Key() As Object _
Implements IDictionaryEnumerator.Key
Get
Try
Return CType(_people(position), DictionaryEntry).Key
Catch e As IndexOutOfRangeException
Throw New InvalidOperationException()
End Try
End Get
End Property
Public ReadOnly Property Value() As Object _
Implements IDictionaryEnumerator.Value
Get
Try
Return CType(_people(position), DictionaryEntry).Value
Catch e As IndexOutOfRangeException
Throw New InvalidOperationException()
End Try
End Get
End Property
End Class
Комментарии
Инструкция foreach
языка C# (for each
в Visual Basic) позволяет скрыть сложный механизм перечислителей. Поэтому вместо непосредственного управления перечислителем рекомендуется использовать foreach
.
Перечислители могут использоваться для чтения данных в коллекции, но не для ее изменения.
Изначально перечислитель располагается перед первым элементом коллекции. Метод Reset также переводит перечислитель в эту позицию. В этой позиции Current свойство не определено. Поэтому необходимо вызвать метод MoveNext, чтобы переместить перечислитель к первому элементу коллекции до считывания значения свойства Current.
Current возвращает тот же объект, пока не будет вызван метод MoveNext или Reset. MoveNext задает Current в качестве значения для следующего элемента.
Если MoveNext передает конец коллекции, перечислитель размещается после последнего элемента в коллекции и MoveNext возвращает значение false
. Если перечислитель находится в этой позиции, последующие вызовы также MoveNext возвращают .false
Если последний вызов MoveNext возвращал false
, Current значение не определено. Чтобы снова задать в качестве значения свойства Current первый элемент коллекции, можно последовательно вызвать методы Reset иMoveNext.
Перечислитель является допустимым до тех пор, пока коллекция остается неизменной. Если в коллекцию вносятся изменения, например добавляются, изменяются или удаляются элементы, перечислитель становится недействительным без возможности восстановление, а его поведение не определено.
У перечислителя нет эксклюзивного доступа к коллекции, поэтому перечисление коллекции не является потокобезопасной процедурой. Чтобы гарантировать потокобезопасность, можно заблокировать коллекцию на время всего перечисления. Чтобы разрешить доступ к коллекции из нескольких потоков для чтения и записи, необходимо реализовать собственную синхронизацию.