Продолжая использовать наш сайт, вы даете согласие на обработку файлов cookie, которые обеспечивают правильную работу сайта. Благодаря им мы улучшаем сайт!
Принять и закрыть

Читать, слущать книги онлайн бесплатно!

Электронная Литература.

Бесплатная онлайн библиотека.

Читать: ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание - Эндрю Троелсен на бесплатной онлайн библиотеке Э-Лит


Помоги проекту - поделись книгой:

то правила CLS остаются выполненными, и вы можете быть уверены, что теперь любой язык .NET сможет вызвать метод Add().

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

Гарантия CLS-совместимости

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

// Указание компилятору C# выполнить проверку на соответствие CLS.

[assembly: System.CLSCompliant(true)]

В главе 12 будут рассмотрены тонкости программирования на основе использования атрибутов, Пока что важно просто понять, что атрибут [CLSCompliant] дает компилятору C# указание проверять каждую строку программного кода на соответствие правилам CLS. Если обнаружится нарушение правил CLS, вы получите сообщение об ошибке компиляции и описание некорректного программного кода.

Общеязыковая среда выполнения

В дополнение к спецификациям CTS и CLS, последней на данный момент аббревиатурой, которую мы рассмотрим, будет аббревиатура CLR (Common Language Runtime – общеязыковая среда выполнения). Для программирования термин среда, выполнения можно понимать, как набор внешних сервисов, необходимых для выполнения данной скомпилированной единицы программного кода. Например» когда разработчик при создании нового приложения использует библиотеку базовых классов Microsoft (MFC), он знает, что для выполнения его программы потребуется соответствующий выполняемый модуль библиотеки MFC (т.е. mfc42.dll). Другие популярные языки также предлагают соответствующие выполняемые модули. Программисты VB6 привязаны к одному или двум выполняемым модулям (например, msvbvm60.dll). Разработчики Java привязаны к виртуальной машине Java (JVM) и т.д.

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

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

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

На рис. 1.3 показана система связей, возникающих между вашим исходным кодом (использующим типы из библиотеки базовых классов), .NET-компилятором и механизмом выполнения .NET.

Различия между компоновочными блоками, пространствами имен и типами

Каждый из нас понимает важность библиотек программного кода. Цель библиотек, таких как MFC, J2EE или ATL, – дать разработчику готовый набор блоков уже существующего программного кода, опираясь на которые можно строить новые приложения. Но язык C# не предлагает библиотек с программным кодом для конкретного языка. Разработчики C# могут использовать .NET-библиотеки, нейтральные в языковом отношении. Для того чтобы все типы в библиотеках базовых классов были правильно организованы, платформа .NET предлагает использовать понятие пространства имен.

Упрощенно говоря, пространство имен является группой связанных типов, содержащихся в компоновочном блоке. Например, пространство имен System.IO содержит типы, связанные с операциями ввода-вывода, пространство имен System.Data определяет основные типы для работы с базами данных и т.д. Важно понимать, что один компоновочный блок (такой как, например, mscorlib.dll) может содержать любое число пространств имен, каждое из которых может, в свою очередь, содержать любое число типов.

Чтобы ситуация стала более ясной, взгляните на рис. 1.4, на котором показан снимок окна Object Browser из Visual Studio 2005. Этот инструмент позволяет видеть компоновочные блоки, на которые ссылается текущий проект, пространства имен, содержащиеся в компоновочных блоках, типы, существующие в пределах данного пространства имен, и члены каждого типа.

Обратите внимание на то, что mscorlib.dll содержит очень много самых разных пространств имея, и в каждом из этих пространств имен содержатся свои семантически связанные типы.


Рис. 1.3. Модуль mscoree.dll в действии

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


Рис.1.4. Один компоновочный блок может содержать любое количество пространств имен

Для иллюстрации рассмотрим следующие три программы, представляющие вариации вездесущего примера "Hello World" соответственно на C#, VB .NET и Managed Extensions for C++.

// Hello world на языке C#

using System;

public class MyApp {

 static void Main() {

  Console.WriteLine("Привет из C#");

 }

}

' Hello world на языке VB .NET

Imports System

Public Module MyApp

 Sub Main()

  Console.WriteLine("Привет из VB .NET")

 End Sub

End Module

// Hello world на языке Managed Extensions for C++

#include "stdafx.h"

using namespace System;

int main(array‹System::String^› ^args) {

 Console::WriteLine("Привет из managed C++");

 return 0;

}

Заметим, что здесь в любом из языков используется класс Console, определенный в пространстве имен System. Если отбросить незначительные синтаксические вариации, то эти три приложения выглядят очень похожими, как по форме, так и по логике.

Очевидно, вашей главной целью, как разработчика .NET. является получение исчерпывающей информации обо всем разнообразии типов, определенных в рамках (многочисленных) пространств имен .NET. Главным из пространств имен, о которых следует знать, является System. Это пространство имен предлагает базовый набор типов, которые вы, как разработчик .NET. будете использовать снова и снова. Фактически вы не сможете построить ни одного реально работающего C#-приложеиия, не сославшись, как минимум, на пространство имен System. В табл. 3.4 предлагаются краткие описания некоторых (но, конечно же, не всех) пространств имен .NET.

Таблица 1.4. Пространства имен .NET

Пространства имен .NET Описание
System В рамках System вы найдете множество полезных типов, связанных с внутренними данными, математическими вычислениями, переменными окружения, генерированием случайных чисел и сбором мусора, а также с обработкой типичных исключительных ситуаций и атрибутов
System.Collections System.ColIections.Generiс Эти пространства имен определяют ряд контейнерных объектов (ArrayList, Queue и т.д.), а также базовых типов и интерфейсов, которые позволяют строить пользовательские коллекции. В .NET 2.0 типы коллекций обладают дополнительными общими возможностями
System.Data System.Data.Odbc System.Data.OracleClient System.Data.OleDb System.Data.SqlClient Эти пространства имен используются для взаимодействия с базами данных на основе ADO.NET
System.Diagnostics Здесь вы найдете множество типов, которые могут использоваться для программной отладки и трассировки исходного кода
System.Drawing System.Drawing.Drawing2D System.Drawing.Printing Здесь вы найдете множество типов для работы с графическими примитивами, такими как растровые изображения, шрифты и пиктограммы, а также для вывода на печать
System.IO System.IO.Compression System.IO.Ports Эти пространства имен включают средства файлового ввода-вывода, буферизации и т.д. В .NET 2.0 пространства имен IO предлагают поддержку сжатия и работы с портами
System.Net Это пространство имен (как и другие родственные пространства имен) содержит типы, связанные с сетевым программированием (запросы/ответы, сокеты, конечные точки соединений и т.д.)
System.Reflection System.Reflection.Emit Эти пространства имен определяют типы, связанные с обнаружением типов в среде выполнения и динамическим созданием типов
System.Runtime.InteropServices Это пространство имен обеспечивает средства взаимодействия типов .NET с "неуправляемым программным кодом" (это, например, DLL на базе C и COM-серверы)
System.Runtime.Remoting Это пространство имен (среди прочих) определяет типы, используемые для построения решений на основе возможностей слоя удаленного доступа .NET
System.Security Безопасность – это неотъемлемый аспект платформы .NET. В пространствах имен, объединенных идеей безопасности, вы найдете множество типов, связанных с разрешением доступа, криптографической защитой и т.д.
System.Threading Это пространство имен определяет типы, используемые при построении многопоточных приложений
System.Web Ряд пространств имен, специально предназначенных для разработки Web-приложений .NET, включая Web-сервисы ASP.NET и XML
System.Windows.Forms Это пространство имен содержит типы, которые упрощают процесс создания традиционных GUI-приложений (приложений с графическим интерфейсом) для настольных систем
System.Xml Связанные с XML пространства имен, содержащие множество типов, используемых для взаимодействия с XML-данными

Программный доступ к пространствам имен

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

В C# ключевое слово using упрощает ссылки на типы, определенные в данном пространстве имен. Вот как оно используется. Допустим, вы строите традиционное приложение для настольной системы. В главном окне должна отображаться некоторая диаграмма, основанная на информации, полученной от внутренней базы данных, и логотип компании. Конечно, для изучения типов в пространствах имен требуется время, но вот несколько очевидных "кандидатов", подходящих для ссылок в описанной выше программе.

// Пространства имен, необходимые для данного приложения.

using System; // Общие типы базовых классов,

using System.Drawing; // визуализация графики,

using System.Windows.Forms; // GDI-элементы,

using System.Data; // общий доступ к данным,

using System.Data.SqlClient; // доступ к данным MS SQL Server.

Выбрав некоторое число пространств имен (и указав ссылки на компоновочные блоки, которые их определяют), вы получаете возможность создавать экземпляры соответствующих типов. Например, если вы хотите создать экземпляр класса Bitmap (из пространства имен System.Drawing), вы можете использовать следующий программный коя,

// Явный список пространств имен, используемых в данном файле.

using System;

using System.Drawing;

class MyApp {

 public void DisplayLogo() {

  // Создание изображения 20x20.

  Bitmap companyLogo = new Bitmap(20, 20);

  ...

 } 

}

Поскольку ваше приложение ссылается на System.Drawing, компилятор сможет выяснить, что класс Bitmap является членом указанного пространства имен. Если бы вы не указали здесь пространство имен System.Drawing, то получили бы ошибку компиляций. Но для определения переменных можно также использовать полностью определённое, или абсолютное имя.

// Здесь System.Drawing не указывается!

Using System;

class MyApp {

 public void DisplayLogo() {

  // Использование абсолютного имени

  System.Drawing.Bitmap companyLogo = new System.Drawing.Bitmap(20, 20);

  …

 }

}

Использование абсолютных имен для определения типа, конечно, упрощает понимание программного кода, но я думаю, и вы не станете возражать, что ключевое слово C# using уменьшает объем необходимого ввода. В этом тексте мы будем избегать использования абсолютных имен (за исключением тех случаев, когда из-за этого возникает явная неоднозначность), отдавая предпочтение использованию ключевого слова using.

При этом следует понимать, что использование using является лишь альтернативой использования абсолютных имен, поскольку в программном коде CIL всегда используются абсолютные имена, так что оба указанных подхода дают совершенно одинаковые результаты в CIL и с точки зрения производительности, и с точки зрения размера компоновочного блока.

Ссылки на внешние компоновочные блоки

Вдобавок к указанию пространства имен с помощью ключевого слова C# using, необходимо указать компилятору C# имя компоновочного блока, содержащего реальное CIL-определение соответствующего типа. Выше уже упоминалось, что многие базовые пространства имен .NET содержатся в mscorlib.dll. Однако тип System.Drawing.Bitmap содержится в другом компоновочном блоке с именем System.Drawing.dll. Большинство компоновочных блоков .NET Framework размещается в специальном каталоге, называемом GAC (Global Assembly Cache - глобальный кэш компоновочных блоков). На машинах Windows это может быть каталог %windir%\Assembly, как показано на рис. 1.5.


Рис. 1.5. Библиотеки базовых классов в GAC

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

Использование ildasm.exe

Если вас пугает перспектива освоения всех пространств имен платформы .NET, вспомните о том, что уникальность любого пространства имен заключается в том, что оно содержит типы, некоторым образом семантически связанные между собой. Поэтому, например, если вам не нужен интерфейс пользователя для простого консольного приложения, то смело можете забыть (среди прочих) о пространствах имен System.Windows.Forms и System.Web. Если вы строите приложение для работы с изображениями, то вам вряд ли понадобятся пространства имен для работы с базами данных. К тому же, как в случае любой новой библиотеки готового программного кода, вы можете учиться по ходу дела.

Утилита ildasm.exe (Intermediate Language Disassembler utility – утилита дизассемблера промежуточного языка) позволяет загрузить любой компоновочный блок .NET и исследовать его содержимое, включая соответствующий манифест, программный код CIL и метаданные типов.

По умолчанию файл ildasm.exe должен быть установлен в папку C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin (если вы не можете найти ildasm.exe в указанном месте, просто выполните поиск файла по ключу "ildasm.exe" на своей машине).

Обнаружив и запустив этот файл, а открывшемся окне выберите команду меню File→Open и перейдите к компоновочному блоку, который вы хотите исследовать. С целью иллюстрации здесь (рис. 1.6) показав компоновочный блок CSharpCalculator.exe, о котором уже шла речь выше. Утилита ildasm.exe представляет структуру компоновочного блока, используя всем знакомый формат дерева просмотра.


Рис. 1.6. Ваш новый лучший друг ildasm.exe

Просмотр CIL-кода

В дополнение к тому, что вы можете видеть пространства имен, типы и их члены в компоновочном блоке. Ildasm.exe дозволяет также просмотреть CIL-инструкции любого члена. Например, если выбрать двойным щелчком метод Main() класса CalcApp, то появится отдельное окно, в котором будет отображаться соответствующий CIL-код (рис. 1.7).


Рис. 1.7. Просмотр CIL-кода

Просмотр метаданных типов

Если вы захотите просмотреть метаданные типов для загруженного в настоящий момент компоновочного блока, просто нажмите ‹Ctrl+M›. На рис. 1.8 показаны метаданные для метода Calc.Add().




Поделиться книгой:

На главную
Назад