myPeople.AddPerson(new Person("Lisa", "Simpson", 9));
myPeople.AddPerson(new Person("Bart", "Simpson", 7));
myPeople.AddPerson(new Person("Maggie", "Simpson", 2));
// Это вызовет ошибку на этапе компиляции!
// myPeople.AddPerson(new Car);
foreach (Person p in myPeople)
{
Console.WriteLine(p);
}
}
Хотя специальные коллекции гарантируют безопасность в отношении типов, такой подход обязывает создавать (в основном идентичные) специальные коллекции для всех уникальных типов данных, которые планируется в них помещать. Таким образом, если нужна специальная коллекция, которая могла бы оперировать только с классами, производными от базового класса Car
using System.Collections;
public class CarCollection : IEnumerable
{
private ArrayList arCars = new ArrayList;
// Приведение для вызывающего кода.
public Car GetCar(int pos) => (Car) arCars[pos];
// Вставка только объектов Car.
public void AddCar(Car c)
{
arCars.Add(c);
}
public void ClearCars
{
arCars.Clear;
}
public int Count => arCars.Count;
// Поддержка перечисления с помощью foreach.
IEnumerator IEnumerable.GetEnumerator => arCars.GetEnumerator;
}
Тем не менее, класс специальной коллекции ничего не делает для решения проблемы с накладными расходами по упаковке/распаковке. Даже если создать специальную коллекцию по имени IntCollection
System.Int32, то все равно придется выделять память под объект какого-нибудь вида, хранящий данные (например, System.Array и ArrayList):public class IntCollection : IEnumerable
{
private ArrayList arInts = new ArrayList;
// Получение int (выполняется распаковка).
public int GetInt(int pos) => (int)arInts[pos];
// Вставка int (выполняется упаковка).
public void AddInt(int i)
{
arInts.Add(i);
}
public void ClearInts
{
arInts.Clear;
}
public int Count => arInts.Count;
IEnumerator IEnumerable.GetEnumerator => arInts.GetEnumerator;
}
Независимо от того, какой тип выбран для хранения целых чисел, в случае применения необобщенных контейнеров затруднительного положения с упаковкой избежать невозможно.
Первый взгляд на обобщенные коллекции
Когда используются классы обобщенных коллекций, все описанные выше проблемы исчезают, включая накладные расходы на упаковку/распаковку и отсутствие безопасности в отношении типов. К тому же необходимость в создании специального класса (обобщенной) коллекции становится довольно редкой. Вместо построения уникальных классов, которые могут хранить объекты людей, автомобилей и целые числа, можно задействовать класс обобщенной коллекции и указать тип хранимых элементов. Добавьте в начало файла Program.cs
using:using System.Collections.Generic;
Взгляните на показанный ниже метод (добавленный в конец файла Program.cs
List (из пространства имен System.Collection.Generic) для хранения разнообразных видов данных в строго типизированной манере (пока не обращайте внимания на детали синтаксиса обобщений):static void UseGenericList
{
Console.WriteLine("***** Fun with Generics *****\n");
// Этот объект List<> может хранить только объекты Person.
List
morePeople.Add(new Person ("Frank", "Black", 50));
Console.WriteLine(morePeople[0]);
// Этот объект ListO может хранить только целые числа.
List
moreInts.Add(10);
moreInts.Add(2);
Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT