Читать «C# 4.0 полное руководство - 2011» онлайн - страница 625
Герберт Шилдт
using System.Collections.Generic;
class MyClass<T> {
T [ ] array;
public MyClass(T[] a) { array = a;
}
// Этот итератор возвращает символы из массива chrs. public IEnumetator<T> GetEnumerator() {
foreach(T obj in array) yield return obj;
}
}
class GenericItrDemo { static void Main() {
int [ ] nums ={4, 3, 6,
MyClass<int> me = new MyClass<int>(nums);
foreach(int x in me)
Console.Write(x + " ");
Console.WriteLine();
bool[] bVals = { true, true, false, true };
MyClass<bool> mc2 = new MyClass<bool>(bVals);
foreach(bool b in mc2)
Console.Write(b + " ");
Console.WriteLine ();
}
}
Вот к какому результату приводит выполнение этой программы.
4 3 6 4 7 9
True True False True
В данном примере массив, состоящий из возвращаемых по очереди объектов, передается конструктору класса MyClass. Тип этого массива указывает в качестве аргумента типа в конструкторе класса MyClass.
Метод GetEnumerator () оперирует данными обобщенного типа Т и возвращает перечислитель типа IEnumerator<T>. Следовательно, итератор, определенный в классе MyClass, способен перечислять данные любого типа.
Инициализаторы коллекций
В С# имеется специальное средство, называемое
List<char> 1st = new List<char>() { 'С1, 'А1, 'Е1, 'В1, 1D1, 1F1 };
После выполнения этого оператора значение свойства 1st. Count будет равно 6, поскольку именно таково число инициализаторов. А после выполнения следующего цикла foreach:
foreach(ch in 1st)
Console.Write(ch + " ");
получится такой результат:
С A E В D F
Для инициализации коллекции типа LinkedListcTKey, TValue>, в которой хранятся пары "ключ-значение", инициализаторы приходится предоставлять парами, как показано ниже.
SortedListcint, string> 1st =
new SortedListcint, string>() { {1, "один11}, {2, "два" }, {3, "три"} };
Компилятор передаст каждую группу значений в качестве аргументов методу Add (). Следовательно, первая пара инициализаторов преобразуется компилятором в вызов Add(1, "один").
Компилятор вызывает метод Add () автоматически для ввода инициализаторов в коллекцию, и поэтому инициализаторы коллекций можно использовать только в коллекциях, поддерживающих открытую реализацию метода Add (). Это означает, что инициализаторы коллекций нельзя использовать в коллекциях типа Stack, Stack<T>, Queue или Queue<T>, поскольку в них метод Add () не поддерживается. Их нельзя применять также в тех коллекциях типа LinkedList<T>, где метод Add () предоставляется как результат явной реализации соответствующего интерфейса.