Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
Книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!
Шрифт:
Интервал:
Закладка:
using System.Collections;
namespace IssuesWithNonGenericCollections
{
public class PersonCollection : IEnumerable
{
private ArrayList arPeople = new ArrayList();
// Приведение для вызывающего кода.
public Person GetPerson(int pos) => (Person)arPeople[pos];
// Вставка только объектов Person.
public void AddPerson(Person p)
{
arPeople.Add(p);
}
public void ClearPeople()
{
arPeople.Clear();
}
public int Count => arPeople.Count;
// Поддержка перечисления с помощью foreach.
IEnumerator IEnumerable.GetEnumerator() => arPeople.GetEnumerator();
}
}
Обратите внимание, что класс PeopleCollection реализует интерфейс IEnumerable, который делает возможной итерацию в стиле foreach по всем элементам, содержащимся в коллекции. Кроме того, методы GetPerson() и AddPerson() прототипированы для работы только с объектами Person, а не растровыми изображениями, строками, подключениями к базам данных или другими элементами. Благодаря определению таких классов теперь обеспечивается безопасность в отношении типов, учитывая, что компилятор C# будет способен выявить любую попытку вставки элемента несовместимого типа. Обновите операторы using в файле Program.cs, как показано ниже, и поместите в конец текущего кода метод UserPersonCollection():
using System;
using System.Collections;
using IssuesWithNonGenericCollections;
// Операторы верхнего уровня в Program.cs
static void UsePersonCollection()
{
Console.WriteLine("***** Custom Person Collection *****n");
PersonCollection myPeople = new PersonCollection();
myPeople.AddPerson(new Person("Homer", "Simpson", 40));
myPeople.AddPerson(new Person("Marge", "Simpson", 38));
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<T> (из пространства имен System.Collection.Generic) для хранения разнообразных видов данных в строго типизированной манере (пока не обращайте внимания на детали синтаксиса обобщений):
static void UseGenericList()
{
Console.WriteLine("***** Fun with Generics *****n");
// Этот объект List<> может хранить только объекты Person.
List<Person> morePeople = new List<Person>();
morePeople.Add(new Person ("Frank", "Black", 50));
Console.WriteLine(morePeople[0]);
// Этот объект ListO может хранить только целые числа.
List<int> moreInts = new List<int>();
moreInts.Add(10);
moreInts.Add(2);
int sum = moreInts[0] + moreInts[1];
// Ошибка на этапе компиляции! Объект Person
// не может быть добавлен в список элементов int!
// moreInts.Add(new Person());
}
Первый контейнер List<T> способен содержать только объекты Person. По этой причине выполнять приведение при извлечении элементов из контейнера не требуется, что делает такой подход более безопасным в отношении типов. Второй контейнер List<T> может хранить только целые числа, размещенные в стеке; другими словами, здесь не происходит никакой скрытой упаковки/распаковки, которая имеет место в необобщенном типе ArrayList. Ниже приведен краткий перечень преимуществ обобщенных контейнеров по сравнению с их необобщенными аналогами.
• Обобщения обеспечивают лучшую производительность, т.к. лишены накладных расходов по упаковке/распаковке, когда хранят типы значений.
•
Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.
Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.
- 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
- 2. Просьба отказаться от оскорблений, угроз и запугиваний.
- 3. Просьба отказаться от нецензурной лексики.
- 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.
Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.
Оставить комментарий
-
Гость Татьяна24 сентябрь 22:20 Как то не очень... Невеста по ошибке. Я не дам тебе развод - Майя Линн
-
Римма24 сентябрь 21:52 Почему главные героинитпкие идиотки? И сюжет не плохой, и написано хорошо. Но как героиня - так дура дурой.... Хозяйка маленького дома, или Любимая для дракона - Кира Рамис
-
Римма20 сентябрь 12:27 Много ненужных пояснений и отступлений. Весь сюжет теряет свою привлекательность. Героиня иногда так тупит, что читать не... Хозяйка приюта для перевертышей и полукровок - Елена Кутукова