How to: Access a Collection Class with foreach (C# Programming Guide)

The following code sample illustrates how to write a non-generic collection class that can be used with foreach. The class is a string tokenizer, similar to the C run-time function strtok_s.

Note

his example represents recommended practice only in cases where you cannot use a generic collection class. Generics are supported in version 2.0 and later of the C# language and the .NET Framework. For an example of how to implement a type-safe generic collection class that supports IEnumerable<T> and thereby avoids the issues discussed below, see How to: Create an Iterator Block for a Generic List (C# Programming Guide).

In the following example, Tokens breaks the sentence "This is a sample sentence." into tokens using ' ' and '-' as separators, and enumerates those tokens with the foreach statement:

Internally, Tokens uses an array, which implements IEnumerator and IEnumerable itself. The code example could have used the array's enumeration methods as its own, but that would have defeated the purpose of this example.

In C#, it is not strictly necessary for a collection class to inherit from IEnumerable and IEnumerator in order to be compatible with foreach; as long as the class has the required GetEnumerator, MoveNext, Reset, and Current members, it will work with foreach. Omitting the interfaces has the advantage of allowing you to define the return type of Current to be more specific than object, thereby providing type-safety.

For example, starting with the sample code above, change the following lines:

The disadvantage of omitting IEnumerable and IEnumerator is that the collection class is no longer interoperable with the foreach statements, or equivalents, of other common language runtime-compatible languages.

You can have the best of both worlds, type-safety within C# and interoperability with other common language runtime-compatible languages, by inheriting from IEnumerable and IEnumerator and using explicit interface implementation as demonstrated in the following example.