Kniga-Online.club
» » » » Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Читать бесплатно Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен. Жанр: Программирование год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:
коллекцию, которая способна хранить только объекты Person, можно определить переменную-член System.Collection.ArrayList внутри класса по имени PeopleCollection и сконфигурировать все члены для оперирования со строго типизированными объектами Person, а не с объектами типа System.Object. Ниже приведен простой пример (специальная коллекция производственного уровня могла бы поддерживать множество дополнительных членов и расширять абстрактный базовый класс из пространства имен System.Collections или System.Collections.Specialized):

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. Ниже приведен краткий перечень преимуществ обобщенных контейнеров по сравнению с их необобщенными аналогами.

• Обобщения обеспечивают лучшую производительность, т.к. лишены накладных расходов по упаковке/распаковке, когда хранят типы значений.

Перейти на страницу:

Эндрю Троелсен читать все книги автора по порядку

Эндрю Троелсен - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


Язык программирования C#9 и платформа .NET5 отзывы

Отзывы читателей о книге Язык программирования C#9 и платформа .NET5, автор: Эндрю Троелсен. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*