: C# 2008 Programmer

Indexers and Iterators

Indexers and Iterators

Sometimes you may have classes that encapsulate an internal collection or array. Consider the following SpamPhraseList class:

public class SpamPhraseList {
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 string Phrase(int index) {
if (index <= 0 && index < Phrases.Length)
return Phrases[index];
else return string.Empty;
}
}

The SpamPhraseList class has a protected string array called Phrases. It also exposes the Phrase() method, which takes in an index and returns an element from the string array:

SpamPhraseList list = new SpamPhraseList();
Console.WriteLine(list.Phrase(17)); //---psychic---

Because the main purpose of the SpamPhraseList class is to return one of the phrases contained within it, it might be more intuitive to access it more like an array, like this:

SpamPhraseList list = new SpamPhraseList();
Console.WriteLine(list[17]); //---psychic---

In C#, you can use the indexer feature to make your class accessible just like an array. Using the SpamPhraseList class, you can use the this keyword to declare an indexer on the class:

public class SpamPhraseList {
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 string this[int index] {
get {
if (index <= 0 && index < Phrases.Length)
return Phrases[index];
else return string.Empty;
}
set {
if (index >= 0 && index < Phrases.Length)
Phrases[index] = value;
}
}
}

Once the indexer is added to the SpamPhraseList class, you can now access the internal array of string just like an array, like this:

SpamPhraseList list = new SpamPhraseList();
Console.WriteLine(list[17]); //---psychic---

Besides retrieving the elements from the class, you can also set a value to each individual element, like this:

list[17] = "psycho";

The indexer feature enables you to access the internal arrays of elements using array syntax, but you cannot use the foreach statement to iterate through the elements contained within it. For example, the following statements give you an error:

SpamPhraseList list = new SpamPhraseList();
foreach (string s in list) //---error---
Console.WriteLine(s);

To ensure that your class supports the foreach statement, you need to use a feature known as iterators. Iterators enable you to use the convenient foreach syntax to step through a list of items in a class. To create an iterator for the SpamPhraseList class, you only need to implement the GetEnumerator() method, like this:

public class SpamPhraseList {
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 string this[int index] {
get {
if (index <= 0 && index < Phrases.Length)
return Phrases[index];
else return string.Empty;
}
set {
if (index >= 0 && index < Phrases.Length)
Phrases[index] = value;
}
}
public IEnumerator<string> GetEnumerator() {
foreach (string s in Phrases) {
yield return s;
}
}
}

Within the GetEnumerator() method, you can use the foreach statement to iterate through all the elements in the Phrases array and then use the yield keyword to return individual elements in the array.

You can now iterate through the elements in a SpamPhraseList object using the foreach statement:

SpamPhraseList list = new SpamPhraseList();
foreach (string s in list) Console.WriteLine(s);


: 1.097. /Cache: 3 / 1