CollectionBase.GetEnumerator 方法
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
返回循环访问实例的 CollectionBase 枚举数。
public:
virtual System::Collections::IEnumerator ^ GetEnumerator();
public System.Collections.IEnumerator GetEnumerator();
abstract member GetEnumerator : unit -> System.Collections.IEnumerator
override this.GetEnumerator : unit -> System.Collections.IEnumerator
Public Function GetEnumerator () As IEnumerator
返回
实例的CollectionBase一个IEnumerator。
实现
示例
下面的代码示例实现该 CollectionBase 类,并使用该实现来创建对象的集合 Int16 。
using System;
using System.Collections;
public class Int16Collection : CollectionBase {
public Int16 this[ int index ] {
get {
return( (Int16) List[index] );
}
set {
List[index] = value;
}
}
public int Add( Int16 value ) {
return( List.Add( value ) );
}
public int IndexOf( Int16 value ) {
return( List.IndexOf( value ) );
}
public void Insert( int index, Int16 value ) {
List.Insert( index, value );
}
public void Remove( Int16 value ) {
List.Remove( value );
}
public bool Contains( Int16 value ) {
// If value is not of type Int16, this will return false.
return( List.Contains( value ) );
}
protected override void OnInsert( int index, Object value ) {
// Insert additional code to be run only when inserting values.
}
protected override void OnRemove( int index, Object value ) {
// Insert additional code to be run only when removing values.
}
protected override void OnSet( int index, Object oldValue, Object newValue ) {
// Insert additional code to be run only when setting values.
}
protected override void OnValidate( Object value ) {
if ( value.GetType() != typeof(System.Int16) )
throw new ArgumentException( "value must be of type Int16.", "value" );
}
}
public class SamplesCollectionBase {
public static void Main() {
// Create and initialize a new CollectionBase.
Int16Collection myI16 = new Int16Collection();
// Add elements to the collection.
myI16.Add( (Int16) 1 );
myI16.Add( (Int16) 2 );
myI16.Add( (Int16) 3 );
myI16.Add( (Int16) 5 );
myI16.Add( (Int16) 7 );
// Display the contents of the collection using foreach. This is the preferred method.
Console.WriteLine( "Contents of the collection (using foreach):" );
PrintValues1( myI16 );
// Display the contents of the collection using the enumerator.
Console.WriteLine( "Contents of the collection (using enumerator):" );
PrintValues2( myI16 );
// Display the contents of the collection using the Count property and the Item property.
Console.WriteLine( "Initial contents of the collection (using Count and Item):" );
PrintIndexAndValues( myI16 );
// Search the collection with Contains and IndexOf.
Console.WriteLine( "Contains 3: {0}", myI16.Contains( 3 ) );
Console.WriteLine( "2 is at index {0}.", myI16.IndexOf( 2 ) );
Console.WriteLine();
// Insert an element into the collection at index 3.
myI16.Insert( 3, (Int16) 13 );
Console.WriteLine( "Contents of the collection after inserting at index 3:" );
PrintIndexAndValues( myI16 );
// Get and set an element using the index.
myI16[4] = 123;
Console.WriteLine( "Contents of the collection after setting the element at index 4 to 123:" );
PrintIndexAndValues( myI16 );
// Remove an element from the collection.
myI16.Remove( (Int16) 2 );
// Display the contents of the collection using the Count property and the Item property.
Console.WriteLine( "Contents of the collection after removing the element 2:" );
PrintIndexAndValues( myI16 );
}
// Uses the Count property and the Item property.
public static void PrintIndexAndValues( Int16Collection myCol ) {
for ( int i = 0; i < myCol.Count; i++ )
Console.WriteLine( " [{0}]: {1}", i, myCol[i] );
Console.WriteLine();
}
// Uses the foreach statement which hides the complexity of the enumerator.
// NOTE: The foreach statement is the preferred way of enumerating the contents of a collection.
public static void PrintValues1( Int16Collection myCol ) {
foreach ( Int16 i16 in myCol )
Console.WriteLine( " {0}", i16 );
Console.WriteLine();
}
// Uses the enumerator.
// NOTE: The foreach statement is the preferred way of enumerating the contents of a collection.
public static void PrintValues2( Int16Collection myCol ) {
System.Collections.IEnumerator myEnumerator = myCol.GetEnumerator();
while ( myEnumerator.MoveNext() )
Console.WriteLine( " {0}", myEnumerator.Current );
Console.WriteLine();
}
}
/*
This code produces the following output.
Contents of the collection (using foreach):
1
2
3
5
7
Contents of the collection (using enumerator):
1
2
3
5
7
Initial contents of the collection (using Count and Item):
[0]: 1
[1]: 2
[2]: 3
[3]: 5
[4]: 7
Contains 3: True
2 is at index 1.
Contents of the collection after inserting at index 3:
[0]: 1
[1]: 2
[2]: 3
[3]: 13
[4]: 5
[5]: 7
Contents of the collection after setting the element at index 4 to 123:
[0]: 1
[1]: 2
[2]: 3
[3]: 13
[4]: 123
[5]: 7
Contents of the collection after removing the element 2:
[0]: 1
[1]: 3
[2]: 13
[3]: 123
[4]: 7
*/
Imports System.Collections
Public Class Int16Collection
Inherits CollectionBase
Default Public Property Item(index As Integer) As Int16
Get
Return CType(List(index), Int16)
End Get
Set
List(index) = value
End Set
End Property
Public Function Add(value As Int16) As Integer
Return List.Add(value)
End Function 'Add
Public Function IndexOf(value As Int16) As Integer
Return List.IndexOf(value)
End Function 'IndexOf
Public Sub Insert(index As Integer, value As Int16)
List.Insert(index, value)
End Sub
Public Sub Remove(value As Int16)
List.Remove(value)
End Sub
Public Function Contains(value As Int16) As Boolean
' If value is not of type Int16, this will return false.
Return List.Contains(value)
End Function 'Contains
Protected Overrides Sub OnInsert(index As Integer, value As Object)
' Insert additional code to be run only when inserting values.
End Sub
Protected Overrides Sub OnRemove(index As Integer, value As Object)
' Insert additional code to be run only when removing values.
End Sub
Protected Overrides Sub OnSet(index As Integer, oldValue As Object, newValue As Object)
' Insert additional code to be run only when setting values.
End Sub
Protected Overrides Sub OnValidate(value As Object)
If Not GetType(System.Int16).IsAssignableFrom(value.GetType()) Then
Throw New ArgumentException("value must be of type Int16.", "value")
End If
End Sub
End Class
Public Class SamplesCollectionBase
Public Shared Sub Main()
' Creates and initializes a new CollectionBase.
Dim myI16 As New Int16Collection()
' Adds elements to the collection.
myI16.Add( 1 )
myI16.Add( 2 )
myI16.Add( 3 )
myI16.Add( 5 )
myI16.Add( 7 )
' Display the contents of the collection using For Each. This is the preferred method.
Console.WriteLine("Contents of the collection (using For Each):")
PrintValues1(myI16)
' Display the contents of the collection using the enumerator.
Console.WriteLine("Contents of the collection (using enumerator):")
PrintValues2(myI16)
' Display the contents of the collection using the Count property and the Item property.
Console.WriteLine("Initial contents of the collection (using Count and Item):")
PrintIndexAndValues(myI16)
' Searches the collection with Contains and IndexOf.
Console.WriteLine("Contains 3: {0}", myI16.Contains(3))
Console.WriteLine("2 is at index {0}.", myI16.IndexOf(2))
Console.WriteLine()
' Inserts an element into the collection at index 3.
myI16.Insert(3, 13)
Console.WriteLine("Contents of the collection after inserting at index 3:")
PrintIndexAndValues(myI16)
' Gets and sets an element using the index.
myI16(4) = 123
Console.WriteLine("Contents of the collection after setting the element at index 4 to 123:")
PrintIndexAndValues(myI16)
' Removes an element from the collection.
myI16.Remove(2)
' Display the contents of the collection using the Count property and the Item property.
Console.WriteLine("Contents of the collection after removing the element 2:")
PrintIndexAndValues(myI16)
End Sub
' Uses the Count property and the Item property.
Public Shared Sub PrintIndexAndValues(myCol As Int16Collection)
Dim i As Integer
For i = 0 To myCol.Count - 1
Console.WriteLine(" [{0}]: {1}", i, myCol(i))
Next i
Console.WriteLine()
End Sub
' Uses the For Each statement which hides the complexity of the enumerator.
' NOTE: The For Each statement is the preferred way of enumerating the contents of a collection.
Public Shared Sub PrintValues1(myCol As Int16Collection)
Dim i16 As Int16
For Each i16 In myCol
Console.WriteLine(" {0}", i16)
Next i16
Console.WriteLine()
End Sub
' Uses the enumerator.
' NOTE: The For Each statement is the preferred way of enumerating the contents of a collection.
Public Shared Sub PrintValues2(myCol As Int16Collection)
Dim myEnumerator As System.Collections.IEnumerator = myCol.GetEnumerator()
While myEnumerator.MoveNext()
Console.WriteLine(" {0}", myEnumerator.Current)
End While
Console.WriteLine()
End Sub
End Class
'This code produces the following output.
'
'Contents of the collection (using For Each):
' 1
' 2
' 3
' 5
' 7
'
'Contents of the collection (using enumerator):
' 1
' 2
' 3
' 5
' 7
'
'Initial contents of the collection (using Count and Item):
' [0]: 1
' [1]: 2
' [2]: 3
' [3]: 5
' [4]: 7
'
'Contains 3: True
'2 is at index 1.
'
'Contents of the collection after inserting at index 3:
' [0]: 1
' [1]: 2
' [2]: 3
' [3]: 13
' [4]: 5
' [5]: 7
'
'Contents of the collection after setting the element at index 4 to 123:
' [0]: 1
' [1]: 2
' [2]: 3
' [3]: 13
' [4]: 123
' [5]: 7
'
'Contents of the collection after removing the element 2:
' [0]: 1
' [1]: 3
' [2]: 13
' [3]: 123
' [4]: 7
注解
C# 语言的 foreach 语句(for each Visual Basic)隐藏枚举器的复杂性。 因此,建议使用 foreach ,而不是直接操作枚举器。
枚举器可用于读取集合中的数据,但不能用于修改基础集合。
最初,枚举器位于集合中的第一个元素之前。 Reset 还将枚举器带回此位置。 在此位置,调用 Current 将引发异常。 因此,在读取值MoveNext之前,必须调用Current枚举器将枚举器提升到集合的第一个元素。
Current返回相同的对象,直到调用或MoveNextReset调用。 MoveNext 设置为 Current 下一个元素。
如果 MoveNext 传递集合的末尾,则枚举器位于集合中的最后一个元素之后并 MoveNext 返回 false。 当枚举器处于此位置时,后续调用 MoveNext 也会返回 false。 如果返回MoveNext的最后一次调用false,则调用Current将引发异常。 若要再次设置为 Current 集合的第一个元素,可以调用 Reset 后跟 MoveNext。
只要集合保持不变,枚举器就保持有效。 如果对集合进行了更改(例如添加、修改或删除元素),枚举器将不可恢复地失效,并且下次调用 MoveNext 或 Reset 时会引发 InvalidOperationException 异常。 如果集合在两Current者之间MoveNext进行了修改,Current则返回它设置为的元素,即使枚举器已失效。
枚举器不具有对集合的独占访问权限;因此,通过集合进行枚举本质上不是线程安全过程。 即使集合同步,其他线程仍可以修改集合,这会导致枚举器引发异常。 若要保证枚举期间的线程安全性,可以在整个枚举期间锁定集合,也可以捕获由其他线程所做的更改导致的异常。
GetEnumerator虽然此方法默认情况下对 COM 客户端不可见,但继承该CollectionBase类可能会公开该方法,并可能导致 COM 客户端中出现不良行为。
此方法是一个 O(1) 操作。