IOrderedDictionary.GetEnumerator Metoda
Definicja
Zwraca moduł wyliczający, który wykonuje iterację IOrderedDictionary kolekcji.Returns an enumerator that iterates through the IOrderedDictionary collection.
public:
System::Collections::IDictionaryEnumerator ^ GetEnumerator();
public System.Collections.IDictionaryEnumerator GetEnumerator ();
abstract member GetEnumerator : unit -> System.Collections.IDictionaryEnumerator
Public Function GetEnumerator () As IDictionaryEnumerator
Zwraca
IDictionaryEnumeratorDla całej IOrderedDictionary kolekcji.An IDictionaryEnumerator for the entire IOrderedDictionary collection.
Implementuje
Przykłady
Poniższy przykład kodu demonstruje implementację prostego IOrderedDictionary opartego na ArrayList klasie.The following code example demonstrates the implementation of a simple IOrderedDictionary based on the ArrayList class. Zaimplementowane IOrderedDictionary są przechowywane pierwsze nazwy jako klucze i nazwiska jako wartości, z dodanym wymaganiem, które każda Pierwsza nazwa jest unikatowa.The implemented IOrderedDictionary stores first names as the keys and last names as the values, with the added requirement that each first name is unique. Ten kod jest częścią większego przykładu kodu podanego dla IOrderedDictionary klasy.This code is part of a larger code example provided for the IOrderedDictionary class.
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
Uwagi
foreach
Instrukcja języka C# ( for each
w Visual Basic) ukrywa złożoność modułów wyliczających.The foreach
statement of the C# language (for each
in Visual Basic) hides the complexity of the enumerators. W związku z tym użycie foreach
jest zalecane zamiast bezpośredniego manipulowania modułem wyliczania.Therefore, using foreach
is recommended instead of directly manipulating the enumerator.
Moduły wyliczające mogą służyć do odczytu danych w kolekcji, ale nie można za ich pomocą modyfikować kolekcji źródłowej.Enumerators can be used to read the data in the collection, but they cannot be used to modify the underlying collection.
Początkowo moduł wyliczający jest umieszczony przed pierwszym elementem w kolekcji.Initially, the enumerator is positioned before the first element in the collection. Reset przywraca również moduł wyliczający z powrotem do tego położenia.Reset also brings the enumerator back to this position. W tym miejscu Current Właściwość jest niezdefiniowana.At this position, the Current property is undefined. W związku z tym MoveNext przed przeczytaniem wartości parametru należy wywołać metodę wyliczającą do pierwszego elementu kolekcji Current .Therefore, you must call MoveNext to advance the enumerator to the first element of the collection before reading the value of Current.
Current zwraca ten sam obiekt do momentu MoveNext Reset wywołania metody lub.Current returns the same object until either MoveNext or Reset is called. MoveNext ustawia Current do następnego elementu.MoveNext sets Current to the next element.
Jeśli MoveNext przekazuje koniec kolekcji, moduł wyliczający jest umieszczony po ostatnim elemencie w kolekcji i MoveNext zwraca false
.If MoveNext passes the end of the collection, the enumerator is positioned after the last element in the collection and MoveNext returns false
. Gdy moduł wyliczający znajduje się w tym miejscu, kolejne wywołania MoveNext również zwracają false
.When the enumerator is at this position, subsequent calls to MoveNext also return false
. Jeśli ostatnie wywołanie MoveNext zwrócone false
, Current nie jest zdefiniowane.If the last call to MoveNext returned false
, Current is undefined. Aby Current ponownie ustawić na pierwszy element kolekcji, możesz wywołać metodę Reset i MoveNext .To set Current to the first element of the collection again, you can call Reset followed by MoveNext.
Moduł wyliczający zachowuje ważność tak długo, jak długo kolekcja pozostaje niezmieniona.An enumerator remains valid as long as the collection remains unchanged. Jeśli w kolekcji zostaną wprowadzone zmiany, takie jak dodanie, zmodyfikowanie czy usunięcie elementów, moduł wyliczający jest nieodwracalnie unieważniany, a jego zachowanie staje się niezdefiniowane.If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and its behavior is undefined.
Moduł wyliczający nie ma wyłącznego dostępu do kolekcji, w związku z tym wyliczanie w kolekcji nie jest wewnętrznie procedurą odporną na wielowątkowość.The enumerator does not have exclusive access to the collection; therefore, enumerating through a collection is intrinsically not a thread-safe procedure. Aby zagwarantować bezpieczeństwo wątków podczas wyliczania, można zablokować kolekcję podczas całego procesu wyliczania.To guarantee thread safety during enumeration, you can lock the collection during the entire enumeration. Aby zezwolić wielu wątkom na dostęp do kolekcji w celu odczytu i zapisu danych, należy zaimplementować własny mechanizm synchronizacji.To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.