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'
};
}
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 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;
}
}
}
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.