List nums = new List();
nums.Add(4);
nums.Add(1);
nums.Add(3);
nums.Add(5);
nums.Add(7);
nums.Add(2);
nums.Add(8);
//---sorts the list---
nums.Sort();
//---prints out all the elements in the list---
foreach (int n in nums) Console.WriteLine(n);
If you try to sort an ArrayListobject containing elements of different types, you are likely to run into an exception because the compiler may not be able to compare the values of two different types.
Sometimes you may have classes that encapsulate an internal collection or array. Consider the following SpamPhraseListclass:
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 SpamPhraseListclass 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 SpamPhraseListclass 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 SpamPhraseListclass, 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 SpamPhraseListclass, 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 foreachstatement 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 foreachstatement, you need to use a feature known as iterators. Iterators enable you to use the convenient foreachsyntax to step through a list of items in a class. To create an iterator for the SpamPhraseListclass, 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 GetEnumerator() {
foreach (string s in Phrases) {
yield return s;
}
}
}
Within the GetEnumerator()method, you can use the foreachstatement to iterate through all the elements in the Phrasesarray and then use the yieldkeyword to return individual elements in the array.
You can now iterate through the elements in a SpamPhraseListobject using the foreachstatement:
SpamPhraseList list = new SpamPhraseList();
foreach (string s in list) Console.WriteLine(s);
Implementing IEnumerable and IEnumerator
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 IEnumerableand IEnumeratorinterfaces. The generic equivalents of these two interfaces are IEnumerableand IEnumerator, 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) interface. The objects enumerated must implement the IEnumerator(or the generic IEnumerable) 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 IEnumerableinterface 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 IEnumerableand IEnumeratorinterfaces because they are type-safe.
To understand how the IEnumerableand IEnumeratorinterfaces work, modify SpamPhraseListclass to implement the IEnumerableinterface:
Читать дальше