Основная идея в данном случае заключается в том, что различные операционные системы могут поддерживать некоторые или все из этих модулей (что зависит от характеристик этих операционных систем). Так, PDA потенциально мог бы поддерживать все основные функциональные возможности .NET, однако маловероятно, чтобы ему потребовались какие-либо более хитрые модули.
Часть библиотеки .NETFramework посвящена описанию некоторых базисных типов. Тип — это способ представления данных; определение наиболее фундаментальных из них (например 32-разрядного целого со знаком) облегчает совместное использование языков программирования с помощью .NETFramework. Все вместе это называется CommonTypeSystem (CTS — единая система типов)
Кроме вындописанной библиотеки, в состав системы входит также NETCommonLanguageRuntime (CLR — единая система выполнения программ), которая ответственна за поддержку выполнения всех приложении, разработанных с использованием библиотеки .NET,
Как можно создавать приложения с помощью .NETFramework
Создание приложений с помощью .NETFramework означает написание программы (на любом из языков программирования, поддерживаемых системой) посредством использования библиотеки программ. В этой книге для наших разработок мы будем использовать VS, который представляет собой мощную интегрированную среду разработки, поддерживающую С# (а также управляемый и не управляемый
С+ + , VisualBasic.NET и некоторые другие языки программирования). Преимуществом данной среды является та простота, с которой возможности .NET могут быть интегрированы в наши программы. Код, который мы будем создавать, будет целиком написан на С#, однако в нем повсеместно будут использоваться возможности .NETFramework, а там, где возникнет необходимость, мы будем применять в VS дополнительные инструменты.
Для того чтобы написанная на С# программа могла быть выполнена, ее необходимо преобразовать в язык, понятный операционной системе, на которой эта программа будет выполняться; такой язык известен под названием родного кода. Подобное преобразование называется компиляцией программы н выполняется компилятором. Однако в .NET этот процесс состоит нз двух этапов.
MSIL и ЛТ
При компиляции кода, в котором используется библиотека .NETFramework, мы не получаем сразу родной код для конкретной операционной системы. Напротив, наша программа будет откомпилирована в программу на языке MicrosoftIntermediateLanguage (MSIL — промежуточный язык компании Microsoft). Этот код не является специфическим ни для какой операционной системы и так же точно не является специфическим для С#. Компиляция с других языков программирования .NET — например с VisualBasic.NET — на первом этапе тоже происходит на этот язык. Данный этап компиляции выполняется VS в тех случаях, когда мы используем его для разработки приложений на С#,
Очевидно, что для запуска приложения потребуется сделать некоторую дополнительную работу. Эта работа возлагается на ЛТ-компилятор (Just-In-Time, своевременный), который осуществляет компиляцию MSIL-кода на код, специфический для ОС и архитектуры используемого компьютера. Только после этого операционная система может выполнить приложение.
В прошлом часто возникала необходимость транслировать написанную программу в несколько различных приложении, каждое нз которых предназначалось для конкретной операционной системы и архитектуры центрального процессора, Нередко это был один нз способов оптимизации (направленной на то, чтобы программа, к примеру, быстрее выполнялась на AMD-чнпах), но иногда это оказывалось критичным (например, когда приходилось использовать некоторые приложения одновременно и в среде Win9x, и в среде WinNt/2000). Теперь такая необходимость исчезла, поскольку ЛТ-компнляторы (как и предполагает их название) используют код на языке MSIL, который совершенно независим от компьютера, операционной системы н центрального процессора. Существует несколько различных JIT-компиляторов, каждый нз которых предназначается для некоторой конкретной архитектуры, поэтому для создания родного кода, необходимого в том или ином случае, будет использоваться соответствующий ЛТ-компилятор.
Удобство такого подхода заключается в том, что теперь приходится выполнять существенно меньший объем работы: фактически мы получаем возможность просто забыть о системно-зависимых особенностях и сконцентрироваться на более интересных функциональных возможностях создаваемой программы.
Модули
Когда выполняется компилирование приложения, создаваемый MSIL-код сохраняется в некотором модуле (assembly). В состав таких модулей входят как выполняемые файлы приложений, которые могут быть запущены из Windowsнапрямую и которым для работы не требуется никаких других программ (такие файлы имеют расширение .ехе), так и библиотеки, предназначенные для использования другими приложениями (они имеют расширение .dil).
Кроме данных на языке MSIL, в модулях хранятся метаннформацня (т. е. информация об информации, хранящейся в данном модуле, иначе известная под названием метаданных) и дополнительные ресурсы (дополнительные данные, используемые MSIL, например звуковые и графические файлы). Метаинформация делает модули полностью самоописательными. Для использования модуля не требуется никакой дополнительной информации; другими словами, исключается ситуация, когда не удается добавить необходимые данные в системный регистр, и все подобные ей, что составляло серьезную проблему прн разработке приложений на других платформах.
Отсюда следует, что установка приложений зачастую сводится к простому копированию файлов в директорию удаленного компьютера. Поскольку системам, под управлением которых будет выполняться приложение, не требуется никакой дополнительной информации, мы получаем возможность просто запускать выполняемый файл из этой директории (при условии, что на данном компьютере инсталлирована CLR.NET) без каких-либо дополнительных действий,
Естественно, размещать все необходимое для выполнения приложения в одном месте не обязательно. Существует возможность создавать код, выполняющий задачи, которые могут потребоваться нескольким приложениям. В подобных ситуациях полезно располагать такой многократно используемый код в месте, доступном всем приложениям. В .NETFramework таким местом является GlobalAssemblyCache (GAC — кэш глобальных модулей). Разместить код в таком кэше очень просто: для этого необходимо просто поместить модуль, содержащий соответствующую программу, в директорию, содержащую этот кэш.
Управляемый код
Использование CLR не ограничивается тем моментом, когда мы откомпилировали программу на MSIL, а некоторый ЛТ-компнлятор откомпилировал MSIL в родной код. Код, написанный с помощью .NETFramework, является управляемым на этапе выполнения (данный этап зачастую называется временем выполнения (runtime)). Это означает, что CLR отслеживает выполнение приложений, управляя памятью, межъязыковой отладкой, обеспечением безопасности и т. п.
Напротив, приложения, которые выполняются не под контролем CLR, называются неуправляемыми, и в них можно использовать определенные языки программирования, такие как С + + , для получения, например доступа к функциям нижнего уровня операционной системы. Однако на С# можно писать только код, который выполняется в управляемой среде. Мы будем использовать возможности CLR по управлению кодом и возложим осуществление любых взаимодействий с операционной системой на .NET.
Сборка мусора
Одной нз наиболее важных особенностей управляемого кода является понятие "сборка мусора". Это способ, применяемый в .NET и гарантирующий полное освобождение памяти, использовавшейся приложением, по завершении работы этого приложения. До появления .NET эта задача возлагалась на программистов, и наличие в программе пары простых ошибок могло привести к ситуации, когда огромные блоки памяти таинственным образом исчезали. Обычно это приводило к постепенному замедлению работы компьютера с последующим крахом системы,
Сборка мусора в .NET работает путем как можно более частого инспектирования памяти компьютера и удаления из нее всего, что уже не требуется. Здесь не существует никаких заранее определенных временных рамок; этот процесс может запускаться с частотой несколько тысяч раз в секунду или один раз в несколько секунд, но вы можете быть уверены, что рано нлн поздно это случиться.
В связи с этим программисты должны учитывать несколько важных аспектов. Поскольку подобные действия выполняются в заранее не известные моменты, приложения нужно разрабатывать с учетом этой особенности. Код, который использует большое количество памяти, должен сам очищать память, а не полагаться на автоматическую сборку мусора, тем более что реализовать это не так уж сложно.
Связывание
Существует еще одни момент, который необходимо учитывать в вышеприведенном процессе. Код на С#, который компилируется иа MSIL на шаге 2, совсем не обязательно должен находиться в одном файле. Имеется возможность разнести код приложения по нескольким исходным файлам, которые затем будут скомпилированы в единый модуль. Этот процесс известен под названием "связывание" н является чрезвычайно полезным. Причина такого положения дел заключается в том, что работать с несколькими не очень большими файлами намного легче, чем с одним огромным. Можно выделить логически связанный код в отдельный файл, работа иад которым будет вестись совершенно независимо и о котором можно забыть после того, как произойдет компиляция. Такой подход существенно упрощает выявление конкретных сегментов кода, когда они оказываются нужными, а заодно позволяет командам разработчиков разделить бремя программирования на отдельные куски, которые затем можно выверять без риска повредить правильно работающие сегменты и те части кода, иад которыми трудятся другие программисты.