Книга: C# 2008 Programmer
Implementing IEnumerable and IEnumerator
Implementing IEnumerable<T> and IEnumerator<T>
Besides using the iterators feature in your class to allow clients to step through its internal elements with foreach
, you can make your class support the foreach statement by implementing the IEnumerable
and IEnumerator
interfaces. The generic equivalents of these two interfaces are IEnumerable<T>
and IEnumerator<T>
, respectively.
Use the generic versions because they are type safe.
In .NET, all classes that enumerate objects must implement the IEnumerable
(or the generic IEnumerable<T>
) interface. The objects enumerated must implement the IEnumerator
(or the generic IEnumerable<T>
) interface, which has the following members:
? Current
— Returns the current element in the collection
? MoveNext()
— Advances to the next element in the collection
? Reset()
— Resets the enumerator to its initial position
The IEnumerable
interface has one member:
? GetEnumerator()
— Returns the enumerator that iterates through a collection
All the discussions from this point onward use the generic versions of the IEnumerable
and IEnumerator
interfaces because they are type-safe.
To understand how the IEnumerable<T>
and IEnumerator<T>
interfaces work, modify SpamPhraseList
class to implement the IEnumerable<T>
interface:
public class SpamPhraseList : IEnumerable<string> {
protected string[] Phrases = new string[]{
"pain relief", "paxil", "pharmacy", "phendimetrazine",
"phentamine", "phentermine", "pheramones", "pherimones",
"photos of singles", "platinum-celebs", "poker-chip",
"poze", "prescription", "privacy assured", "product for less",
"products for less", "protect yourself", "psychic"
};
//---for generic version of the class---
public IEnumerator<string> GetEnumerator() {}
//---for non-generic version of the class---
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {}
}
Notice that for the generic version of the IEnumerable
interface, you need to implement two versions of the GetEnumerator()
methods — one for the generic version of the class and one for the nongeneric version.
To ensure that the SpamPhraseList
class can enumerate the strings contained within it, you define an enumerator class within the SpamPhraseList
class:
public class SpamPhraseList : IEnumerable<string> {
private class SpamPhrastListEnum : IEnumerator<string> {
private int index = -1;
private SpamPhraseList spamlist;
public SpamPhrastListEnum(SpamPhraseList sl) {
this.spamlist = sl;
}
//---for generic version of the class---
string IEnumerator<string>.Current {
get {
return spamlist.Phrases[index];
}
}
//---for non-generic version of the class---
object System.Collections.IEnumerator.Current {
get {
return spamlist.Phrases[index];
}
}
bool System.Collections.IEnumerator.MoveNext() {
index++;
return index < spamlist.Phrases.Length;
}
void System.Collections.IEnumerator.Reset() {
index = -1;
}
void IDisposable.Dispose() { }
}
protected string[] Phrases = new string[] {
"pain relief", "paxil", "pharmacy", "phendimetrazine",
"phentamine", "phentermine", "pheramones", "pherimones",
"photos of singles", "platinum-celebs", "poker-chip", "poze",
"prescription", "privacy assured", "product for less",
"products for less", "protect yourself", "psychic"
};
public IEnumerator<string> GetEnumerator() {
return new SpamPhrastListEnum(this);
}
//---for non-generic version of the class---
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return new SpamPhrastListEnum(this);
}
}
In this example, the SpamPhrastListEnum
class implements the IEnumerator<string>
interface and provides the implementation for the Current
property and the MoveNext()
and Reset()
methods.
To print out all the elements contained within a SpamPhraseList
object, you can use the same statements that you used in the previous section:
SpamPhraseList list = new SpamPhraseList();
foreach (string s in list) //---error---
Console.WriteLine(s);
Behind the scenes, the compiler is generating the following code for the foreach statement:
SpamPhraseList list = new SpamPhraseList();
IEnumerator<string> s = list.GetEnumerator();
while (s.MoveNext())
Console.WriteLine((string)s.Current);
- Разработка приложений баз данных InterBase на Borland Delphi
- Open Source Insight and Discussion
- Introduction to Microprocessors and Microcontrollers
- Chapter 6. Traversing of tables and chains
- Chapter 8. Saving and restoring large rule-sets
- Chapter 11. Iptables targets and jumps
- Chapter 5 Installing and Configuring VirtualCenter 2.0
- Chapter 16. Commercial products based on Linux, iptables and netfilter
- Appendix A. Detailed explanations of special commands
- Appendix B. Common problems and questions
- Appendix E. Other resources and links
- IP filtering terms and expressions