Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
40.doc
Скачиваний:
14
Добавлен:
30.04.2022
Размер:
646.66 Кб
Скачать

9.2.1. Постоянство строк

Для представления строк в среде исполнения .NET используется класс System.String, и при любом изменении строки в программе создается новый экземпляр System.String, старый отбрасывается и в дальнейшем подвергается сборщику мусора.

Данное ограничение способствует более эффективной реализации символьных строк. Так, если требуется строка в качестве разновидности уже имеющейся строки, то для этой цели следует создать новую строку, содержащую все необходимые изменения. А поскольку неиспользуемые строковые объекты автоматически собираются в "мусор", то о дальнейшей судьбе ненужных строк можно даже не беспокоиться.

Следует, однако, подчеркнуть, что переменные ссылки на строки (т.е. объекты типа string) подлежат изменению, а следовательно, они могут ссылаться на другой объект. Но содержимое самого объекта типа string не меняется после его создания.

Для того чтобы стало понятнее, почему неизменяемые строки не являются помехой, воспользуемся еще одним методом обращения со строками: Substring(). Этот метод возвращает новую строку, содержащую часть вызывающей строки. В итоге создается новый строковый объект, содержащий выбранную подстроку, тогда как исходная строка не меняется, а следовательно, соблюдается принцип постоянства строк. Ниже приведена рассматриваемая здесь форма метола Substring():

string Substring(int индекс_начала, int длина)

где индекс_начала обозначает начальный индекс исходной строки, а длина — длину выбираемой подстроки.

Ниже приведена программа, в которой принцип постоянства строк демонстрируется на примере использования метода Substring().

// Применить метод Substring().

using System;

class SubStr {

static void Main() {

string orgstr = "В С# упрощается обращение со строками.";

// сформировать подстроку

string substr = orgstr.SubstringE, 20);

Console.WriteLine("orgstr: " + orgstr);

Console.WriteLine("substr: " + substr);

}

}

Вот к какому результату приводит выполнение этой программы.

orgstr: В С# упрощается обращение со строками,

substr: упрощается обращение

Как видите, исходная строка из переменной orgstr не меняется, а выбранная из нее подстрока содержится в переменной substr.

И последнее замечание: несмотря на то, что постоянство строк обычно не является ни ограничением, ни помехой для программирования на С#, иногда оказывается полезно иметь возможность видоизменять строки. Для этой цели в С# имеется класс StringBuilder, который определен в пространстве имен System.Text. Этот класс позволяет создавать строковые объекты, которые можно изменять. Но, как правило, в программировании на С# используется тип string, а не класс StringBuilder.

10. Платформа .Net. Основные понятия и принципы работы

.NET Framework представляет собой программную платформу для создания приложений на базе семейства операционных систем Windows, а также многочисленных операционных систем производства не Microsoft, таких как Mac OS X и различные дистрибутивы Unix и Linux. Для начала не помешает привести краткий перечень некоторых базовых функциональных возможностей, которыми обладает .NET:

- Возможность обеспечения взаимодействия с существующим программным кодом.

- Поддержка для многочисленных языков программирования. Приложения .NET можно создавать с помощью любого множества языков программирования (С#, Visual Basic, F#, S# и т.д.).

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

- Полная и тотальная интеграция языков. В .NET поддерживается межъязыковое наследование, межъязыковая обработка исключений и межъязыковая отладка кода.

- Обширная библиотека базовых классов. Эта библиотека позволяет избегать сложностей, связанных с выполнением прямых вызовов к API-интерфейсу, и предлагает согласованную объектную модель, которую могут использовать все поддерживающие .NET языки.

Тремя ключевыми (и связанными между собой) сущностями, которые и делают предоставление этих преимуществ возможным, являются: CLR, CTS и CLS.

С точки зрения программиста .NET представляет собой исполняющую среду и обширную библиотеку базовых классов. Уровень исполняющей среды называется общеязыковой исполняющей средой (Common Language Runtime) или, сокращенно, средой CLR. Главной задачей CLR является автоматическое обнаружение, загрузка и управление типами .NET (вместо программиста). Кроме того, среда CLR заботится о ряде низкоуровневых деталей, таких как управление памятью, обслуживание приложения, обработка потоков и выполнение различных проверок, связанных с безопасностью.

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

Основной механизм CLR физически имеет вид библиотеки под названием mscoree.dll (и также называется общим механизмом выполнения исполняемого кода объектов — Common Object Runtime Execution Engine). При добавлении ссылки на сборку для ее использования загрузка библиотеки mscoree.dll осуществляется автоматически и затем, в свою очередь, приводит к загрузке требуемой сборки в память.

Механизм исполняющей среды отвечает за выполнение целого ряда задач:

1) определение места расположения сборки;

2) обнаружение запрашиваемого типа в двоичном файле;

3) размещение типа в памяти;

4) преобразование CIL-кода в соответствующие платформе инструкции;

5) произведение необходимых проверок безопасности

6) непосредственное выполнение самого запрашиваемого кода.

Помимо загрузки пользовательских сборок и создания пользовательских типов, механизм CLR при необходимости будет взаимодействовать и с типами, содержащимися в библиотеках базовых классов .NET. Хотя вся библиотека базовых классов поделена на ряд отдельных сборок, главной среди них является сборка mscorlib.dll. В этой сборке содержится большое количество базовых типов, охватывающих широкий спектр типичных задач программирования, а также базовых типов данных, применяемых во всех языках .NET. При построении .NET-решений доступ к этой конкретной сборке будет предоставляться автоматически.

Другим составляющим компонентом платформы .NET является общая система типов (Common Type System) или, сокращенно, система CTS. В спецификации CTS представлено полное описание всех возможных типов данных и программных конструкций, поддерживаемых исполняющей средой, того, как эти сущности могут взаимодействовать друг с другом, и того, как они могут представляться в формате метаданных .NET.

Важно понимать, что любая из определенных в CTS функциональных возможностей может не поддерживаться в отдельно взятом языке, совместимом с .NET. Поэтому существует еще общеязыковая спецификация (Common Language Specification) или, сокращенно, спецификация CLS, в которой описано лишь то подмножество общих типов и программных конструкций, каковое способны воспринимать абсолютно все поддерживающие .NET языки программирования. Следовательно, в случае построения типов .NET только с функциональными возможностями, которые предусмотрены в CLS, можно оставаться полностью уверенным в том, что все совместимые с .NET языки смогут их использовать. И, наоборот, в случае применения такого типа данных или конструкции программирования, которой нет в CLS, рассчитывать на то, что каждый язык программирования .NET сможет взаимодействовать с подобной библиотекой кода .NET, нельзя.

CLS представляет собой набор правил, которые во всех подробностях описывают минимальный и полный комплект функциональных возможностей, которые должен обязательно поддерживать каждый отдельно взятый .NET-компилятор для того, чтобы генерировать такой программный код, который мог бы обслуживаться CLR и к которому в то же время могли бы единообразным образом получать доступ все языки, ориентированные на платформу .NET. Во многих отношениях CLS может считаться просто подмножеством всех функциональных возможностей, определенных в CTS.

В конечном итоге CLS является своего рода набором правил, которых должны придерживаться создатели компиляторов при желании, чтобы их продукты могли без проблем функционировать в мире .NET. Каждое из этих правил имеет простое название (например, "Правило CLS номер 6") и описывает, каким образом его действие касается тех, кто создает компиляторы, и тех, кто (каким-либо образом) будет взаимодействовать с ними. Самым главным в CLS является правило 1, гласящее, что правила CLS касаются только тех частей типа, которые делаются доступными за пределами сборки, в которой они определены.

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

Помимо среды CLR и спецификаций CTS и CLS, в составе платформы .NET поставляется библиотека базовых классов, которая является доступной для всех языков программирования .NET. В этой библиотеке не только содержатся определения различных примитивов, таких как потоки, файловый ввод-вывод, системы графической визуализации и механизмы для взаимодействия с различными внешними устройствами, но также предоставляется поддержка для целого ряда служб, требуемых в большинстве реальных приложений.

Например, в библиотеке базовых классов содержатся определения типов, которые способны упрощать процесс получения доступа к базам данных, манипулирования XML-документами, обеспечения программной безопасности и создания веб-, а также обычных настольных и консольных интерфейсов. На высоком уровне взаимосвязь между CLR, CTS, CLS и библиотекой базовых классов выглядит так, как показано на рис. 2.

Рис. 2. Отношение между CLR, CTS, CLS и библиотеками базовых классов

Наиболее важным моментом, о котором следует знать, программируя на С#, является то, что с помощью этого языка можно создавать только такой код, который будет выполняться в исполняющей среде .NET. Официально код, ориентируемый на выполнение в исполняющей среде .NET, называется управляемым кодом (managed code), двоичная единица, в которой содержится такой управляемый код — сборкой (assembly), а код, который не может обслуживаться непосредственно в исполняющей среде .NET — неуправляемым кодом (unmanaged code). Сборка получается при создании файла *.dll или *.exe с помощью .NET-компилятора.

Важно понимать, что двоичные .NЕТ-единицы содержат не специфические, а наоборот, не зависящие от платформы инструкции на промежуточном языке (Intermediate Language — IL), а также метаданные типов. На рис. 3 показано, как все это выглядит схематически.

Рис. 3. Генерация IL-инструкций и метаданных

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

Помимо CIL-инструкций, в сборках также содержатся метаданные, которые детально описывают особенности каждого имеющегося внутри данной двоичной .NET-единицы "типа". Например, при наличии класса по имени MyClass они будут описывать детали наподобие того, как выглядит базовый класс этого класса MyClass, какие интерфейсы реализует MyClass (если вообще реализует), а также, подробно, какие члены он поддерживает. Метаданные .NET всегда предоставляются внутри сборки и автоматически генерируются компилятором соответствующего распознающего .NET языка.

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

Одним из самых важных преимуществ такого подхода является интеграция языков: все компиляторы .NET генерируют примерно одинаковые CIL-инструкции. Кроме того, поскольку CIL не зависит от платформы, .NET Framework тоже получается не зависящей от платформы.

Из-за того, что в сборках содержатся CIL-инструкции, а не инструкции, ориентированные на конкретную платформу, CIL-код перед использованием должен обязательно компилироваться на лету. Объект, который отвечает за компиляцию CIL-кода в понятные ЦП инструкции, называется оперативным (just-in-time — JIT) компилятором.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]