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

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

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

System.Collections — не единственное пространство имен .NET Core, которое содержит необобщенные классы коллекций. В пространстве имен System.Collections.Specialized определено несколько специализированных типов коллекций. В табл. 10.3 описаны наиболее полезные типы в этом конкретном пространстве имен, которые все являются необобщенными.

Кроме указанных конкретных типов классов пространство имен System.Collections.Specialized также содержит много дополнительных интерфейсов и абстрактных базовых классов, которые можно применять в качестве стартовых точек для создания специальных классов коллекций. Хотя в ряде ситуаций такие "специализированные" типы могут оказаться именно тем, что требуется в ваших проектах, здесь они рассматриваться не будут. И снова во многих ситуациях вы с высокой вероятностью обнаружите, что пространство имен System.Collections.Generic предлагает классы с похожей функциональностью, но с добавочными преимуществами.

На заметку! В библиотеках базовых классов .NET Core доступны два дополнительных пространства имен, связанные с коллекциями (System.Collections.ObjectModel и System.Collections.Concurrent). Первое из них будет объясняться позже в главе, когда вы освоите тему обобщений. Пространство имен System.Collections.Concurrent предоставляет классы коллекций, хорошо подходящие для многопоточной среды (многопоточность обсуждается в главе 15).

Проблемы, присущие необобщенным коллекциям

Хотя на протяжении многих лет с использованием необобщенных классов коллекций (и интерфейсов) было построено немало успешных приложений .NET и .NET Core, опыт показал, что применение этих типов может привести к возникновению ряда проблем.

Первая проблема заключается в том, что использование классов коллекций System.Collections и System.Collections.Specialized в результате дает код с низкой производительностью, особенно в случае манипулирования числовыми данными (например, типами значений). Как вы вскоре увидите, когда структуры хранятся в любом необобщенном классе коллекции, прототипированном для оперирования с System.Object, среда CoreCLR должна осуществлять некоторое количество операций перемещения в памяти, что может нанести ущерб скорости выполнения.

Вторая проблема связана с тем, что большинство необобщенных классов коллекций не являются безопасными в отношении типов, т.к. они были созданы для работы с System.Object и потому могут содержать в себе вообще все что угодно. Если разработчик нуждался в создании безопасной в отношении типов коллекции (скажем, контейнера, который способен хранить объекты, реализующие только определенный интерфейс), то единственным реальным вариантом было создание нового класса коллекции вручную. Хотя задача не отличалась высокой трудоемкостью, решать ее было несколько утомительно.

Прежде чем вы увидите, как применять обобщения в своих программах, полезно чуть глубже рассмотреть недостатки необобщенных классов коллекций, что поможет лучше понять проблемы, которые был призван решить механизм обобщений. Создайте новый проект консольного приложения по имени IssuesWithNongenericCollections, импортируйте пространства имен System и System.Collections в начале файла Program.cs и удалите оставшийся код:

using System;

using System.Collections;

Проблема производительности

Как уже было указано в главе 4, платформа .NET Core поддерживает две обширные категории данных: типы значений и ссылочные типы. Поскольку в .NET Core определены две основные категории типов, временами возникает необходимость представить переменную одной категории как переменную другой категории. Для этого в C# предлагается простой механизм, называемый упаковкой (boxing), который позволяет хранить данные типа значения внутри ссылочной переменной. Предположим, что в методе по имени SimpleBoxUnboxOperation() создана локальная переменная типа int. Если где-то в приложении понадобится представить такой тип значения как ссылочный тип, то значение придется упаковать:

static void SimpleBoxUnboxOperation()

{

  // Создать переменную ValueType (int).

  int myInt = 25;

  // Упаковать int в ссылку на object.

  object boxedInt = myInt;

}

Упаковку можно формально определить как процесс явного присваивания данных типа значения переменной System.Object. При упаковке значения среда CoreCLR размещает в куче новый объект и копирует в него величину типа значения (в данном случае 25). В качестве результата возвращается ссылка на вновь размещенный в куче объект.

Противоположная операция также разрешена и называется распаковкой (unboxing). Распаковка представляет собой процесс преобразования значения, хранящегося в объектной ссылке, обратно в соответствующий тип значения в стеке. Синтаксически операция распаковки выглядит как обычная операция приведения, но ее семантика несколько отличается. Среда CoreCLR начинает с проверки того, что полученный тип данных эквивалентен упакованному типу, и если это так, то копирует значение в переменную, находящуюся в стеке. Например, следующие операции распаковки работают успешно при условии, что лежащим в основе типом boxedInt действительно является int:

static void SimpleBoxUnboxOperation()

{

  // Создать переменную ValueType (int).

  int myInt = 25;

  // Упаковать int в ссылку на object.

  object boxedInt = myInt;

  // Распаковать ссылку обратно в int.

  int unboxedInt = (int)boxedInt;

}

Когда компилятор C# встречает синтаксис упаковки/распаковки, он выпускает код CIL, который содержит коды операций box/unbox. Если вы просмотрите сборку с помощью утилиты ildasm.exe, то обнаружите в ней показанный далее код CIL:

.method assembly hidebysig static

    void  '<<Main>$>g__SimpleBoxUnboxOperation|0_0'() cil managed

{

  .maxstack  1

  .locals init (int32 V_0, object V_1, int32 V_2)

    IL_0000:  nop

    IL_0001:  ldc.i4.s   25

    IL_0003:  stloc.0

    IL_0004:  ldloc.0

    IL_0005:  box        [System.Runtime]System.Int32

    IL_000a:  stloc.1

    IL_000b:  ldloc.1

    IL_000c:  unbox.any  [System.Runtime]System.Int32

    IL_0011:  stloc.2

    IL_0012:  ret

  } // end of method '<Program>$'::'<<Main>$>g__SimpleBoxUnboxOperation|0_0'

Помните, что в отличие от обычного приведения распаковка обязана осуществляться только в подходящий тип данных. Попытка распаковать порцию данных в некорректный тип приводит к генерации исключения InvalidCastException. Для обеспечения высокой безопасности каждая операция распаковки должна быть помещена внутрь конструкции try/catch, но такое действие со всеми операциями распаковки в приложении может оказаться достаточно трудоемкой задачей. Ниже показан измененный код, который выдаст ошибку из-за того, что в нем предпринята попытка распаковки упакованного значения int в тип long:

static void SimpleBoxUnboxOperation()

{

  // Создать переменную ValueType (int).

  int myInt = 25;

  // Упаковать int в ссылку на object.

  object boxedInt = myInt;

  // Распаковать в неподходящий тип данных, чтобы

  // инициировать исключение времени выполнения.

  try

  {

    long unboxedLong = (long)boxedInt;

 

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

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

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


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

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


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

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

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


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