IEnumerator<T> Интерфейс
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Поддерживает простую итерацию по универсальной коллекции.
generic <typename T>
public interface class IEnumerator : IDisposable, System::Collections::IEnumerator
public interface IEnumerator<out T> : IDisposable, System.Collections.IEnumerator
public interface IEnumerator<T> : IDisposable, System.Collections.IEnumerator
type IEnumerator<'T> = interface
interface IEnumerator
interface IDisposable
type IEnumerator<'T> = interface
interface IDisposable
interface IEnumerator
Public Interface IEnumerator(Of Out T)
Implements IDisposable, IEnumerator
Public Interface IEnumerator(Of T)
Implements IDisposable, IEnumerator
Параметры типа
- T
Тип объектов для перечисления.
Это ковариантный параметр типа. Это означает, что вы можете использовать любой из указанных типов или любой тип, являющийся более производным. Дополнительные сведения о ковариантности и контрвариантности см. в статье Ковариантность и контрвариантность в универсальных шаблонах.- Производный
- Реализации
Примеры
В следующем примере показана реализация интерфейса IEnumerator<T> для класса коллекции пользовательских объектов. Пользовательский объект — это экземпляр типа Box
, а класс коллекции — BoxCollection
. Этот пример кода является частью более крупного примера, предоставленного для интерфейса ICollection<T>.
// Defines the enumerator for the Boxes collection.
// (Some prefer this class nested in the collection class.)
public class BoxEnumerator : IEnumerator<Box>
{
private BoxCollection _collection;
private int curIndex;
private Box curBox;
public BoxEnumerator(BoxCollection collection)
{
_collection = collection;
curIndex = -1;
curBox = default(Box);
}
public bool MoveNext()
{
//Avoids going beyond the end of the collection.
if (++curIndex >= _collection.Count)
{
return false;
}
else
{
// Set current box to next item in collection.
curBox = _collection[curIndex];
}
return true;
}
public void Reset() { curIndex = -1; }
void IDisposable.Dispose() { }
public Box Current
{
get { return curBox; }
}
object IEnumerator.Current
{
get { return Current; }
}
}
' Defines the enumerator for the Boxes collection.
' (Some prefer this class nested in the collection class.)
Public Class BoxEnumerator
Implements IEnumerator(Of Box)
Private _collection As BoxCollection
Private curIndex As Integer
Private curBox As Box
Public Sub New(ByVal collection As BoxCollection)
MyBase.New()
_collection = collection
curIndex = -1
curBox = Nothing
End Sub
Private Property Box As Box
Public Function MoveNext() As Boolean _
Implements IEnumerator(Of Box).MoveNext
curIndex = curIndex + 1
If curIndex = _collection.Count Then
' Avoids going beyond the end of the collection.
Return False
Else
'Set current box to next item in collection.
curBox = _collection(curIndex)
End If
Return True
End Function
Public Sub Reset() _
Implements IEnumerator(Of Box).Reset
curIndex = -1
End Sub
Public Sub Dispose() _
Implements IEnumerator(Of Box).Dispose
End Sub
Public ReadOnly Property Current() As Box _
Implements IEnumerator(Of Box).Current
Get
If curBox Is Nothing Then
Throw New InvalidOperationException()
End If
Return curBox
End Get
End Property
Private ReadOnly Property Current1() As Object _
Implements IEnumerator.Current
Get
Return Me.Current
End Get
End Property
End Class
' Defines two boxes as equal if they have the same dimensions.
Public Class BoxSameDimensions
Inherits EqualityComparer(Of Box)
Public Overrides Function Equals(ByVal b1 As Box, ByVal b2 As Box) As Boolean
If b1.Height = b2.Height And b1.Length = b2.Length And b1.Width = b2.Width Then
Return True
Else
Return False
End If
End Function
Public Overrides Function GetHashCode(ByVal bx As Box) As Integer
Dim hCode As Integer = bx.Height ^ bx.Length ^ bx.Width
Return hCode.GetHashCode()
End Function
End Class
Комментарии
IEnumerator<T> является базовым интерфейсом для всех универсальных перечислителей.
Оператор foreach
языка C# (for each
в C++, For Each
в Visual Basic) скрывает сложность перечислителей. Поэтому рекомендуется использовать foreach
вместо непосредственного управления перечислителем.
Перечислители можно использовать для чтения данных в коллекции, но их нельзя использовать для изменения базовой коллекции.
Изначально перечислитель размещается перед первым элементом в коллекции. На этой позиции Current не определен. Поэтому необходимо вызвать MoveNext, чтобы перейти перечислителя к первому элементу коллекции перед чтением значения Current.
Current возвращает тот же объект до вызова MoveNext. MoveNext задает Current следующему элементу.
Если MoveNext передает конец коллекции, перечислитель размещается после последнего элемента в коллекции и MoveNext возвращает false
. Если перечислитель находится в этой позиции, последующие вызовы MoveNext также возвращают false
. Если последний вызов MoveNext возвращен false
, Current не определен. Невозможно снова задать Current для первого элемента коллекции; Вместо этого необходимо создать новый экземпляр перечислителя.
Метод Reset предоставляется для взаимодействия COM. Он не обязательно должен быть реализован; Вместо этого средство реализации может просто создать NotSupportedException. Тем не менее, если вы решили сделать это, необходимо убедиться, что вызывающие пользователи не полагаются на Reset функциональные возможности.
Если изменения вносятся в коллекцию, например добавление, изменение или удаление элементов, поведение перечислителя не определено.
Перечислитель не имеет монопольного доступа к коллекции; Таким образом, перечисление через коллекцию по сути не является потокобезопасной процедурой. Чтобы гарантировать безопасность потоков во время перечисления, можно заблокировать коллекцию во время всего перечисления. Чтобы разрешить доступ к коллекции несколькими потоками для чтения и записи, необходимо реализовать собственную синхронизацию.
Реализации коллекций по умолчанию в пространстве имен System.Collections.Generic не синхронизируются.
Примечания для тех, кто реализует этот метод
Для реализации этого интерфейса требуется реализация негенерического IEnumerator интерфейса. Методы MoveNext() и Reset() не зависят от T
и отображаются только в негенерическом интерфейсе. Свойство Current отображается в обоих интерфейсах и имеет разные типы возвращаемых значений. Реализуйте негенерическое свойство Current как явную реализацию интерфейса. Это позволяет любому потребителю негенерного интерфейса использовать универсальный интерфейс.
Кроме того, IEnumerator<T> реализует IDisposable, что требует реализации метода Dispose(). Это позволяет закрыть подключения к базе данных или освободить дескрипторы файлов или аналогичные операции при использовании других ресурсов. Если нет дополнительных ресурсов для удаления, укажите пустую реализацию Dispose().
Свойства
Current |
Возвращает элемент в коллекции в текущей позиции перечислителя. |
Методы
Dispose() |
Выполняет определяемые приложением задачи, связанные с освобождением, освобождением или сбросом неуправляемых ресурсов. (Унаследовано от IDisposable) |
MoveNext() |
Перемещает перечислитель к следующему элементу коллекции. (Унаследовано от IEnumerator) |
Reset() |
Задает перечислителю начальную позицию, которая перед первым элементом в коллекции. (Унаследовано от IEnumerator) |