Книги в продаже (аннотация + содержание + отрывок)

Э. Троелсен
C# И ПЛАТФОРМА .NET. БИБЛИОТЕКА ПРОГРАММИСТА.
Цена: 210 р.

Источник: Издательский дом 'ПИТЕР'
Разделы: Adobe Photoshop (графический растровый редактор)
Подробнее: Информация от издателя (открывается в новом окне)
Заказ: Оформление покупки (открывается в новом окне)
      Основная цель этой книги — дать читателю прочные знания синтаксиса и семантики C#, а также разобрать особенности архитектуры .NET. После ее прочтения вы познакомитесь со всеми основными областями, охваченными библиотекой базовых классов C#. Для приобретения практических навыков книга содержит множество примеров, иллюстрирующих излагаемый материал. Для работы с книгой не нужен какой-либо предварительный опыт работы с C# и платформой .NET, однако при ее написании авторы ориентировались на тех разработчиков, которые уже имеют опыт работы с одним из современны
      х языков программирования (C++, Visual Basic, Java или каким-либо другим).
     
     
     
      Содержание
      Предисловие
      Благодарности
      Глава 1. Философия .NET
      Современное состояние дел
      Как живут программисты, использующие Win32/C
      Как живут программисты, использующие C++/MFC
      Как живут программисты, использующие Visual Basic
      Как живут программисты, использующие Java
      Как живут COM-программисты
      Как живут программисты, использующие Windows DNA
      Решение .NET
      Строительные блоки .NET (CLR, CTS и CLS)
      Библиотека базовых классов .NET
      Преимущества C#
      Языки программирования .NET
      Обзор двоичных файлов .NET ("сборки")
      Сборки из одного и нескольких файлов
      Роль Microsoft Intermediate Language
      Преимущества IL
      Роль метаданных
      Простой пример метаданных
      Компиляция IL в платформенно-зависимые инструкции
      Типы .NET и пространства имен .NET
      Основы Common Language Runtime - среды выполнения .NET
      Стандартная система типов CTS
      Классы CTS
      Структуры CTS
      Интерфейсы CTS
      Члены типов CTS
      Перечисления CTS
      Делегаты CTS
      Встроенные типы данных CTS
      Основы CLS
      Работа с пространствами имен
      Важнейшие пространства имен .NET
      Использование пространств имен в коде приложения
      Обращения к внешним сборкам
      Как получить дополнительную информацию о пространствах имен и типах
      ILDasm.exe
      Выгрузка в файл иерархии типов и членов сборки
      Выгрузка в файл вместе с инструкциями IL
      Просмотр метаданных типов
      Web-приложение ClassViewer
      Графическое приложение WinCV
      Создание приложений C# с использованием компилятора командной строки
      Ссылки на внешние сборки
      Компиляция нескольких исходных файлов
      Создание приложений C# с использованием интегрированной среды разработки Visual Studio.NET
      Начало работы со средой Visual Studio.NET
      Окно Solution Explorer
      Окно Properties
      Экономное размещение кода на экране
      Ссылки на внешние сборки
      Отладка в Visual Studio.NET
      Работа с окном Server Explorer
      Средства для работы с XML
      Поддержка диаграмм UML
      Утилита Object Browser
      Средства для работы с базами данных
      Встроенная справка
      Подведение итогов
      Глава 2. Основы языка C#
      Анатомия класса C#
      Как еще можно объявить метод Main()
      Обработка параметров командной строки
      Создание объектов: конструкторы
      Будет ли происходить утечка памяти?
      Композиция приложения C#
      Инициализация членов
      Ввод и вывод с использованием класса Console
      Средства форматирования строк в C#
      Структурные и ссылочные типы
      Структурные и ссылочные типы: исследуем дальше
      Точка отсчета для любых типов: System.Object
      Замещение методов System.Object
      Статические члены System.Object
      Системные типы данных и псевдонимы C#
      Избранные заметки о некоторых типах данных
      От структурного типа к ссылочному типу и наоборот: упаковка и распаковка
      Значения по умолчанию для встроенных типов данных
      Константы
      Циклы в C#
      Выражение for
      Выражение foreach/in
      Выражения while и do/while
      Средства управления логикой работы программ
      в C# Дополнительные операторы C#
      Определение пользовательских методов класса
      Модификаторы уровня доступа к методам
      Статические методы и методы экземпляров
      Статические данные
      Интересное рядом: некоторые статические члены класса Environment
      Модификаторы для параметров методов
      Работа с массивами
      Многомерные массивы
      Базовый класс System.Array
      Работа со строками
      Управляющие последовательности и вывод служебных символов
      Применение System.Text.StringBuilder
      Перечисления C#
      Базовый класс System.Enum
      Определение структур в C#
      Еще раз об упаковке и распаковке
      Определяем пользовательские пространства имен
      Применение пространств имен для разрешения конфликтов между именами классов
      Использование псевдонимов для имен классов
      Вложенные пространства имен
      Подведение итогов
      Глава 3. C# и объектно-ориентированное программирование
      Формальное определение класса в C#
      Ссылки на самого себя
      Определение открытого интерфейса по умолчанию
      Указание области видимости на уровне типа: открытые и внутренние типы
      Столпы объектно-ориентированного программирования
      Инкапсуляция
      Наследование: отношения "быть" и "иметь"
      Полиморфизм: классический и для конкретного случая
      Средства инкапсуляции в C#
      Реализация инкапсуляции при помощи традиционных методов доступа и изменения
      Второй способ инкапсуляции: применение свойств класса
      Внутреннее представление свойств C#
      Свойства только для чтения, только для записи и статические
      Псевдоинкапсуляция: создание полей "только для чтения"
      Статические поля "только для чтения"
      Поддержка наследования в C#
      Работа с конструктором базового класса
      Можно ли производить наследование от нескольких базовых классов
      Хранение "семейных тайн": ключевое слово protected
      Запрет наследования: классы, объявленные как sealed
      Применение модели включения-делегирования
      Определение вложенных типов
      Поддержка полиморфизма в C#
      Абстрактные классы
      Принудительный полиморфизм: абстрактные методы
      Контроль версий членов класса
      Приведение типов в C#
      Приведение числовых типов
      Обработка исключений
      Генерация исключения
      Перехват исключений
      Создание пользовательских исключений, первый этап
      Создание пользовательских исключений, второй этап
      Обработка нескольких исключений
      Блок finally
      Последние замечания о работе с исключениями
      Жизненный цикл объектов
      Завершение ссылки на объект
      Завершение в подробностях
      Создание метода удаления для конкретного случая
      Интерфейс IDisposable
      Взаимодействие со сборщиком мусора
      Оптимизация сборки мусора
      Подведение итогов
      Глава 4. Интерфейсы и коллекции
      Программирование с использованием интерфейсов
      Реализация интерфейса
      Получение ссылки на интерфейс
      Интерфейсы как параметры
      Явная реализация интерфейса
      Создание иерархий интерфейсов
      Наследование от нескольких базовых интерфейсов
      Создание пользовательского нумератора (интерфейсы IEnumerable и IEnumerator)
      Создание клонируемых объектов (интерфейс ICloneable)
      Создание сравниваемых объектов (интерфейс IComparable)
      Сортировка по нескольким идентификаторам (IComparer)
      Как с помощью специальных свойств сделать сортировку более удобной
      Пространство имен System.Collections
      Пространство имен System.Collections.Specialized
      Применение ArrayList
      Подведение итогов
      Глава 5. Дополнительные возможности классов C#
      Создание пользовательского индексатора
      Перегрузка операторов
      Перегрузка операторов равенства
      Перегрузка операторов сравнения
      Последние замечания о перегрузке операторов
      Делегаты
      Пример делегата
      Делегаты как вложенные типы
      Члены System.MulticastDelegate
      Применение CarDelegate
      Анализ работы делегата
      Многоадресность
      Делегаты, указывающие на обычные функции
      События
      Как работают события
      Прием событий
      Объекты как приемники событий
      Реализация обработки событий с использованием интерфейсов
      Документирование в формате XML
      Просмотр файла документации в формате XML
      Создание документации в формате HTML
      Подведение итогов
      Глава 6. Сборки, потоки и домены приложений
      Проблемы с классическими двоичными файлами
      COM
      Проблема: работа с версиями COM
      Проблема: развертывание приложений COM
      Обзор сборок .NET
      Сборки из одного и нескольких файлов
      Логическое и физическое представление сборки
      Сборки обеспечивают повторное использование кода
      Сборки - контейнеры для типов
      В сборках предусмотрены встроенные средства самоописания и контроля версий
      Сборки определяют контекст безопасности
      Разные версии сборок могут выполняться параллельно
      Создание тестовой однофайловой сборки
      Клиентское приложение C#
      Клиентское приложение Visual Basic.NET
      Межъязыковое наследование
      Подробности манифеста CarLibrary
      Метаданные и код IL для типов CarLibrary
      Частные сборки
      Технология "зондирования"
      Идентификация частной сборки
      Частные сборки и файлы конфигурации приложений
      Процесс загрузки частной сборки в целом
      Сборки для общего доступа
      Проблемы с GAC?
      Общие ("сильные") имена сборок
      Создание сборки для общего пользования
      Установка сборки в глобальный кэш сборок (GAC)
      Применение сборки для общего пользования в приложении
      Политика версий .NET
      Запись информации о версии
      Работа с разными версиями SharedAssembly
      Создаем SharedAssembly версии 2.0
      Политика версий .NET по умолчанию
      Управление загрузкой разных версий сборок
      Администраторский файл конфигурации
      Работа с потоками в традиционных приложениях Win32
      Проблемы одновременности и синхронизации потоков
      Что такое домен приложения
      Работаем с доменами приложений
      Пространство имен System.Threading
      Работа с классом Thread
      Запуск вторичных потоков
      Именованные потоки
      Параллельная работа потоков
      Как "усыпить" поток
      Одновременный доступ к данным из разных потоков
      Ключевое слово lock
      Использование System.Threading.Monitor
      Применение System.Threading.Interlocked
      Подведение итогов
      Глава 7. Рефлексия типов и программирование с использованием атрибутов
      Что такое рефлексия типов
      Класс Type
      Получение объекта класса Type
      Возможности класса Type
      Типы пространства имен System.Reflection
      Загрузка сборки
      Вывод информации о типах в сборке
      Вывод информации о членах класса
      Вывод информации о параметрах метода
      Применение позднего связывания
      Класс System.Activator
      Применение динамических сборок
      Знакомство с пространством имен System.Reflection.Emit
      Создаем динамическую сборку
      Как использовать динамическую сборку
      Программирование с использованием атрибутов
      Работа с существующими атрибутами
      Создание пользовательских атрибутов
      Как ограничить использование атрибута определенными типами
      Атрибуты уровня сборки и модуля
      Файл AssemblyInfo.cs
      Как работать с атрибутами в процессе выполнения программы
      Подведение итогов
      Глава 8. Окна становятся лучше: введение в Windows.Forms
      Два главных пространства имен для организации графического интерфейса
      Обзор пространства имен Windows.Forms
      Взаимодействие с типами Windows.Forms
      Создание нового проекта
      Создание главного окна приложения (вручную)
      Создание проекта Windows Forms
      Класс System.Windows.Forms.Application
      Работаем с классом Application
      Реагируем на событие ApplicationExit
      Препроцессинг сообщений при помощи класса Application
      Анатомия формы
      Классы System.Object и MarshalByRefObject
      Класс Component
      Класс Control
      Настройка стиля формы
      События класса Control
      Работаем с классом Control
      Реагируем на события мыши: часть первая
      Реагируем на события мыши: часть вторая
      Реагируем на события клавиатуры
      Еще немного о классе Control
      Painting Basics
      Класс ScrollableControl
      Класс ContainerControl
      Класс Form
      Используем возможности класса Form
      Создаем меню
      Вложенный класс Menu$MenuItemCollection
      Создание системы меню в приложении
      Добавляем еще одно меню верхнего уровня
      Создаем контекстное меню
      Дополнительные возможности меню
      Создаем меню при помощи IDE Visual Sudio.NET
      Что такое строка состояния
      Создаем строку состояния
      Работаем с классом Timer
      Отображение в строке состояния подсказок к пунктам меню
      Создаем панель инструментов
      Создаем панели инструментов при помощи Visual Studio IDE
      Создаем набор изображений (объект ImageList) при помощи
      Visual Studio
      Пример приложения Windows Forms для работы с реестром и журналом событий Windows 2000
      Взаимодействие с системным реестром
      Взаимодействие с журналом событий Windows 2000
      Как считать информацию из журнала событий
      Подведение итогов
      Глава 9. Графика становится лучше (GDI+)
      Обзор пространств имен GDI+
      Пространство имен System.Drawing
      Служебные типы System.Drawing
      Тип Point(F)
      Тип Rectangle(F)
      Тип Size(F)
      Класс Region
      Сеансы вывода графики
      Как сделать клиентскую область вашего приложения "недействительной"
      Выводим графические объекты без события Paint
      Возможности класса Graphics
      Система координат по умолчанию в GDI+
      Применение альтернативных единиц измерения
      Применение альтернативных точек отсчета
      Работа с цветом
      Возможности класса ColorDialog
      Работа со шрифтами
      Семейства шрифтов
      Единицы измерения для шрифта
      Создаем приложение с возможностью выбора шрифта
      Выводим информацию об установленных шрифтах (System.Drawing.Text)
      Класс FontDialog
      Обзор пространства имен System.Drawing.Drawing2D
      Определение качества вывода графического объекта
      Работа с перьями
      Работаем с "наконечниками" перьев
      Работаем с кистью
      Работаем со штриховыми кистями
      Работаем с текстурными кистями
      Работаем с градиентными кистями
      Вывод изображений
      Перетаскивание, проверка попадания в область, занимаемую изображением,и элемент управления PictureBox
      Еще о проверке попадания
      Проверка попадания в непрямоугольные области
      Работа с форматами реcурсов .NET
      Пространство имен System.Resources
      Создание файлов *.resx программным образом
      Чтение из файлов *.resx программным образом
      Создание файлов *.resources
      Работаем с типом ResourceWriter
      Работаем с типом ResourceManager
      Работа с ресурсами при помощи IDE Visual Studio.NET
      Подведение итогов
      Глава 10. Элементы управления
      Иерархия классов элементов управления
      Как вручную добавить элементы управления на форму
      Класс Control$ControlCollection
      Как добавить элементы управления на форму при помощи Visual Studio
      Элемент управления TextBox
      Некоторые возможности TextBox
      Великая и могучая кнопка (а также родительский класс ButtonBase)
      Выравнивание текста и изображений относительно краев кнопки
      Некоторые возможности работы с кнопками
      Работаем с флажками
      Работаем с переключателями и группирующими рамками
      Элемент управления CheckedListBox
      Списки
      Комбинированные списки
      Настраиваем порядок перехода по Tab
      Tab Order Wizard
      Элемент управления TrackBar
      Элемент управления MonthCalendar
      Еще немного о типе DateTime
      Элементы управления UpDown
      Элемент управления Panel
      Всплывающие подсказки (ToolTips) для элементов управления
      Добавление всплывающей подсказки при помощи графических средств Visual Studio
      Элемент управления ErrorProvider
      Закрепление элемента управления в определенном месте формы
      Стыковка элемента управления с краем формы
      Создание пользовательских диалоговых окон
      Пример использования диалогового окна в приложении
      Как получить данные из диалогового окна
      Наследование форм
      Подведение итогов
      Глава 11. Ввод, вывод и сериализация объектов
      Знакомство с пространством имен System.IO
      Типы Directory(Info) и File(Info)
      Абстрактный класс FileSystemInfo
      Работа с типом DirectoryInfo
      Перечисление FileAttributes
      Получение доступа к файлам через объект DirectoryInfo
      Создаем подкаталоги при помощи класса DirectoryInfo
      Статические члены класса Directory
      Класс FileInfo
      Использование метода FileInfo.Open()
      Методы FileInfo.OpenRead() и FileInfo.OpenWrite()
      Методы FileInfo.OpenText(), FileInfo.CreateText() и FileInfo.AppendText()
      Абстрактный класс Stream
      Работа с объектом FileStream
      Класс MemoryStream
      Класс BufferedStream
      Классы StreamWriter и StreamReader
      Запись в текстовый файл
      Считывание информации из текстового файла
      Класс StringWriter
      Класс StringReader
      Работа с двоичными данными (классы BinaryReader и BinaryWriter)
      Заметки на полях
      Сохранение объектов в .NET
      Графы для отношений объектов
      Настройка объектов для сериализации
      Выбираем объект Formatter
      Пространство имен System.Runtime.Serialization
      Сериализация в двоичном формате
      Сериализация в формате SOAP
      Сериализация в пользовательском формате и интерфейс ISerializable
      Простой пример пользовательской сериализации
      Приложение для регистрации автомобилей с графическим интерфейсом
      Реализация добавления новых объектов Car
      Код сериализации
      Подведение итогов
      Глава 12. Взаимодействие с унаследованным программным кодом
      Главные вопросы совместимости
      Пространство имен System.Runtime.InteropServices
      Взаимодействие с модулями DLL, созданными на C
      Поле ExactSpelling
      Поле CharSet
      Поля CallingConvention и EntryPoint
      Взаимодействие .NET и COM
      Представление типов COM как типов .NET
      Управление ссылками на объекты сокласса
      Сокрытие низкоуровневых интерфейсов COM
      Создание простого COM-сервера в Visual Basic 6.0
      Что находится в IDL нашего COM-сервера
      Создаем простой клиент COM в Visual Basic 6.0
      Импорт библиотеки типов
      Добавление ссылки на сборку
      Раннее связывание с COM-классом CoCalc
      Позднее связывание с соклассом CoCalc
      Особенности созданной нами сборки
      Создаем COM-сервер при помощи ATL
      Добавление методов в интерфейс по умолчанию
      Генерация события COM
      Генерация ошибки COM
      Представление внутренних подобъектов и применение SAFEARRAY
      Последний штрих: создаем перечисление IDL
      Клиент COM-сервера в Visual Basic 6.0
      Создаем сборку и анализируем процесс преобразования
      Преобразование библиотеки типов
      Преобразование интерфейсов COM
      Преобразование атрибутов параметров в коде IDL
      Преобразование иерархии интерфейсов
      Преобразование соклассов и свойств COM
      Преобразование перечислений COM
      Преобразование COM SAFEARRAY
      Перехват событий COM
      Обработка ошибки COM
      Полный код клиента C#
      Обращение клиента COM к сборке .NET
      Роль CCW
      Понятие интерфейса класса
      Определяем интерфейс класса
      Создание типа .NET
      Генерация библиотеки типов и регистрация типов .NET
      Анализ созданной библиотеки типов
      Интерфейс _Object
      Сгенерированное выражение библиотеки
      Просмотр типов .NET в OLE/COM Object Viewer
      Просмотр записей в реестре
      Создаем клиента в Visual Basic 6.0
      Некоторые особенности отображения типов .NET в COM
      Анализ кода COM, сгенерированного для базового класса
      Анализ кода COM, сгенерированного для производного класса
      Управление процессом генерации кода IDL (как повлиять на то, что делает утилита tlbexp.exe)
      Что у нас получилось
      Управление регистрацией промежуточного модуля CCW
      Взаимодействие со службами COM+
      Пространство имен System.EnterpriseServices
      Особенности создания типов .NET для работы
      под COM+ Пример класса C# для работы под COM+
      Добавление атрибутов уровня сборки для COM+
      Помещаем сборку в каталог COM+
      Проверяем установку при помощи Component Services Explorer
      Подведение итогов
      Глава 13. Доступ к данным при помощи ADO.NET
      Почему потребовалось создавать ADO.NET
      ADO.NET: общая картина
      Знакомство с пространствами имен ADO.NET
      Типы пространства имен System.Data
      Тип DataColumn
      Создаем объект DataColumn
      Добавляем объект DataColumn в DataTable
      Делаем столбец первичным ключом таблицы
      Настройка автоматического увеличения значений для столбцов
      Настраиваем представление столбца в формате XML
      Тип DataRow
      Работа со свойством DataRow.RowState
      Работа со свойством ItemArray
      Тип DataTable
      Создаем объект DataTable
      Удаляем строки из таблицы
      Применение фильтров и порядка сортировки для DataTable
      Внесение изменений в строки
      Тип DataView
      Возможности класса DataSet
      Члены класса DataSet
      Создание объекта DataSet
      Моделируем отношения между таблицами при помощи класса DataRelation
      Переход между таблицами, участвующими в отношении
      Чтение и запись объектов DataSet в формате XML
      Создание примера простой базы данных
      Управляемые провайдеры ADO.NET
      Управляемый провайдер OLE DB
      Установление соединения при помощи типа OleDbConnection
      Построение команды SQL
      Работа с OleDbDataReader
      Подключение к базе данных Access
      Выполнение хранимых процедур
      Тип OleDbDataAdapter
      Заполнение данными объекта DataSet при помощи OleDbDataAdapter
      Работа с управляемым провайдером SQL
      Пространство имен System.Data.SqlTypes
      Вставка новых записей при помощи SqlDataAdapter
      Изменение записей в таблице при помощи SqlDataAdapter
      Автоматическое создание команд SQL
      Заполнение объекта DataSet с несколькими таблицами и добавление объектов DataRelations
      Подведение итогов
      Глава 14. Разработка web-приложений и ASP.NET
      Web-приложения и web-серверы
      Что такое виртуальные каталоги
      Структура документа HTML
      Форматирование текста средствами HTML
      Заголовки HTML
      HTML-редактор Visual Studio.NET
      Разработка форм HTML
      Создаем пользовательский интерфейс
      Добавление изображений
      Клиентские скрипты
      Пример клиентского скрипта
      Реализация проверки введенных пользователем данных
      Передаем данные формы (методы GET и POST)
      Синтаксис строки запроса HTTP
      Создание классической страницы ASP
      Принимаем данные, переданные методом POST
      Первое приложение ASP.NET
      Некоторые проблемы классических ASP
      Некоторые преимущества ASP.NET
      Пространства имен ASP.NET
      Наиболее важные типы пространства имен System.Web
      Приложение и сеанс подключения пользователя
      Создание простого web-приложения на C#
      Исходный файл *.aspx
      Файл web.config
      Исходный файл Global.asax
      Простой код ASP.NET на C#
      Архитектура web-приложения ASP.NET
      Тип System.Web.UI.Page
      Связка *.aspx/Codebehind
      Свойство Page.Request
      Свойство Page.Response
      Свойство Page.Application
      Отладка и трассировка приложений ASP.NET
      Элементы управления WebForm
      Создание элементов управления WebForm
      Иерархия классов элементов управления WebForm
      Виды элементов управления WebForm
      Базовые элементы управления WebForm
      Элементы управления с дополнительными возможностями
      Элементы управления для работы с источниками данных
      Элементы управления для проверки вводимых пользователем данных
      Обработка событий элементов управления WebForm
      Подведение итогов
      Глава 15. Web-службы
      Роль web-служб
      Инфраструктура web-службы
      Протокол подключения
      Служба описания
      Служба обнаружения
      Обзор пространств имен web-служб
      Пространство имен System.Web.Services
      Пример элементарной web-службы
      Исходный файл C# для web-службы (*.asmx.cs)
      Реализуем методы web-службы
      Работа клиента с web-службой
      Тип WebMethodAttribute
      Базовый класс System.Web.Services.WebService
      Web Service Description Language (WSDL)
      Протоколы подключения к web-службам
      Обмен данными при помощи HTTP-GET и HTTP-POST
      Обмен данными при помощи SOAP
      Прокси-сборки для web-служб
      Создание прокси-сборки при помощи утилиты wsdl.exe
      Компилируем прокси-сборку
      Создание клиента для работы через прокси-сборку
      Создание прокси-сборки в Visual Studio.NET
      Пример более сложной web-службы (и ее клиентов)
      Сериализация пользовательских типов
      Настраиваем клиента web-службы
      Создание типов для сериализации (некоторые уточнения)
      Протокол обнаружения web-службы
      Добавление новой web-службы
      Подведение итогов
      Алфавитный указатель
     
     
     
     
     
      ОТРЫВОК
     
     
      Философия .NET
      Любому современному программисту, который желает идти в ногу с последними веяниями, каждые несколько лет приходится переучиваться. Языки (C++, Visual Basic, Java), библиотеки (MFC, ATL, STL), архитектуры (COM, CORBA), которые стали вехами в развитии программирования за последние годы, постепенно уходят в тень лучших или по крайней мере более молодых программных технологий. Вне зависимости от того, нравится это программистам или нет, этот процесс неизбежен. Платформа .NET компании Microsoft - это следующая волна коренных изменений, которая идет к нам из Редмонда.
      В этой главе мы рассмотрим основополагающие понятия .NET, к которым мы затем будем обращаться во всех остальных частях книги. Глава начинается с рассмотрения элементов, на которых основана платформа .NET - сборок (assemblies), промежуточного языка (intermediate language, IL) и компиляции в процессе выполнения (just in time compilation, JIT). Мы также рассмотрим взаимосвязи компонентов платформы .NET - Common Language Runtime (CLR), Common Type System (CTS) и Common Language Specification (CLS).
      В этой главе также приведен общий обзор возможностей, которые предоставляют библиотеки базовых классов .NET и утилит (таких как ILDasm.exe), которые помогут вам в работе с этими библиотеками. В самом конце главы мы познакомимся с возможностями компиляции приложений C# с использованием компилятора командной строки (csc.exe) и интегрированной среды разработки (Integrated Development Environment, IDE) Visual Studio.NET.
      Современное состояние дел
      Перед тем как мы вступим в пределы вселенной .NET, полезно будет разобраться с простым вопросом - а зачем, собственно говоря, она нужна? Для этого мы очень кратко рассмотрим те технологии, которые имеются в распоряжении программистов в настоящий момент, их возможности и ограничения, а затем перейдем к тем преимуществам, которые предоставляют C# и платформа .NET в целом.
      Как живут программисты, использующие Win32/C
      Изначально под программированием под Windows подразумевалось программирование на C с использованием Windows Application Programming Interface (интерфейсом прикладного программирования Windows, в 32-разрядных версиях Windows - Win32 API). С использованием этой технологии было создано множество вполне достойных приложений, однако вряд ли кто-нибудь будет спорить с тем, что написание приложения с использованием только Windows API - это очень трудоемкая задача.
      Еще одна проблема заключается в том, что C - достаточно суровый по отношению к программисту язык. Тем, кто создает на нем свои приложения, приходится вручную заниматься управлением памятью, выполнять расчеты при использовании указателей и работать с совершенно неестественными с точки зрения человеческого языка синтаксическими конструкциями. Кроме того, в C, конечно, недостаточно возможностей для объектно-ориентированного программирования. Если вам приходилось связывать тысячи глобальных функций Win32 API в единые гигантские конструкции, вы не будете сил
      ьно удивляться тому, что в подобных приложениях ошибки встречаются очень часто.
      Как живут программисты, использующие C++/MFC
      C++ - это огромный шаг вперед в отношении новых возможностей по сравнению с исходным языком С. Во многих ситуациях C++ вполне допустимо представить как объектно-ориентированную надстройку над C. Такая надстройка позволяет использовать преимущества "столпов" объектно-ориентированного программирования - инкапсуляции, полиморфизма и наследования. Однако программисты, использующие C++, остаются незащищенными от многих и часто опасных особенностей C (теми же самыми низкоуровневыми возможностями работы с памятью и трудными для восприятия синтаксическими конс
      трукциями).
      Существует множество библиотек для C++, основное назначение которых - облегчить написание приложений под Windows, предоставив для этой цели уже готовые классы. Одна из наиболее распространенных библиотек - это MFC (Microsoft Foundation Classes). MFC - это дополнительный уровень над Win32 API, который значительно упрощает работу программиста за счет использования готовых классов, макросов и мастеров. Однако MFC - это лишь частичное решение проблемы. Даже при использовании MFC программисту приходится работать со сложным для чтения кодом, весьма опасным с точки зрения возможных ошибо
      к.
      Как живут программисты, использующие Visual Basic
      Люди всегда стремятся сделать свою жизнь проще. Повинуясь этому стремлению многие программисты на C++ обратили свои взоры к гораздо более простому и дружелюбному языку, каким является Visual Basic (VB). Visual Basic позволяет работать с достаточно сложными элементами интерфейса пользователя, библиотеками кода (например, COM-серверами) и средствами доступа к данным при минимальных затратах времени и сил. Visual Basic в гораздо большей степени, чем MFC, прячет от пользователя вызовы Win32 API и предоставляет большой набор интегрированных средств быстрой разработки.
      Однако у Visual Basic есть и недостатки. Главный из них - это гораздо меньшие возможности, которые предоставляет этот язык, по сравнению с С++ (это утверждение справедливо, по крайней мере, для версий более ранних, чем VB.NET). Visual Basic - это язык "для работы с объектами", а не объектно-ориентированный язык в обычном понимании этого слова. В Visual Basic нет классического наследования, нет поддержки создания параметризованных классов, нет собственных средств создания многопоточных приложений - и этот список можно продолжать еще долго.
      Как живут программисты, использующие Java
      Язык программирования Java - это полностью объектно-ориентированный язык, который в отношении синтаксиса многое унаследовал от C++. Конечно, преимущества Java далеко не исчерпываются межплатформенностью. Язык Java в синтаксическом отношении проще и логичнее, чем C++. Java как платформа предоставляет в распоряжение программистов большое количество библиотек (пакетов), в которых содержится большое количество описаний классов и интерфейсов на все случаи жизни. С их помощью можно создавать стопроцентные приложения Java с возможностью обращения к базам данных, подде
      ржкой передачи почтовых сообщений, с клиентской частью, которой необходим только web-браузер, или наоборот, с клиентской частью, обладающей изощренным интерфейсом.
      Java - это очень элегантный и красивый язык. Однако при его использовании проблем также избежать не удастся. Одна из серьезных проблем заключается в том, что при создании сложного приложения на Java вам придется использовать только этот язык для создания всех частей этого приложения. В Java предусмотрено не так уж много средств для межъязыкового взаимодействия (что понятно ввиду предназначения Java быть единым многоцелевым языком программирования). В реальном мире существуют миллионы строк готового кода, которые хотелось бы интегрировать с новыми приложениям
      и на Java. Однако это сделать очень трудно.
      Java - это далеко не идеальный язык во многих ситуациях. Простой пример - если вы попытаетесь создать только на Java приложение, активно работающее с 3D-графикой, скорее всего, вы обнаружите, что работать такое приложение будет не очень быстро. Немного подумав, вы можете прийти к выводу, что для работы с 3D-графикой лучше использовать код, написанный на языке с более развитыми низкоуровневыми возможностями (например, на C++). Однако интегрировать такой код с кодом на Java вам будет очень сложно. Поскольку возможности для обращения к API компонентов, созданных на других
      языках, в Java очень ограничены, говорить о реальном межъязыковом взаимодействии на основе Java не приходится.
      Как живут COM-программисты
      Современное состояние дел таково, что если вы не строите Java-приложения, то велика вероятность, что вы осваиваете технологию Microsoft Component Object Model (COM). COM-технология провозглашает: "Если вы создаете классы в точном соответствии с требованиями COM, то у вас получится блок повторно используемого программного кода".
      Прелесть двоичного COM-сервера заключается в том, что к нему можно обращаться из любого языка. Например, программисты, использующие C++, могут создавать классы, которые можно будет использовать из приложения на VBasic. Программисты, использующие Delphi, могут использовать классы, созданные на C и т. д. Однако в межъязыковом взаимодействии COM есть свои ограничения. Например, вы не можете произвести новый тип COM от существующего (то есть не можете использовать классическое наследование). Для повторного использования существующих типов COM вам придется использовать др
      угие, гораздо менее надежные и эффективные средства.
      Большое преимущество COM заключается в том, что программист может не заботиться о физическом местонахождении компонентов. Такие средства, как Application Identifiers (AppIDs, идентификаторы приложений), стабы (stubs), прокси, среда выполнения COM, позволяют избегать при обращении к компонентам по сети необходимости помещать в приложение код для работы с сокетами, вызовами RPC и прочими низкоуровневыми механизмами. Достаточно посмотреть на такой код на Visual Basic 6.0 для клиента COM:
      'Этот код на VB 6.0 предназначен для активации класса COM,
      'созданного на любом языке. Класс COM может быть расположен
      'в любом месте на локальном компьютере или в сети.
      Dim c as New MyCOMClass 'Местонахождение класса 'определяется через AppID c.DoSomeWork
      Объектная модель COM используется очень широко. Однако внутреннее устройство компонентов весьма сложно. Чтобы научиться разбираться в нем, вам придется потратить по крайней мере несколько месяцев. Написание приложений с использованием COM-компонентов можно упростить, используя стандартные библиотеки, например библитеку Active Template Library (ATL) со своим набором готовых классов, шаблонов и макросов.
      Некоторые языки (например, Visual Basic) также позволяют скрыть сложность инфраструктуры COM. Однако всех сложностей избежать все равно не удастся. Например, даже если вы работаете с относительно простым и поддерживающим COM Visual Basic, вам придется решать не всегда простые вопросы, связанные с регистрацией компонентов на компьютере и развертыванием приложений.
      Как живут программисты, использующие Windows DNA
      Картина будет неполной, если мы не примем во внимание такую мелочь, как Интернет. За несколько последних лет Microsoft добавила в свои операционные системы большое количество средств для работы с этой средой, в том числе и средства, призванные помочь в создании Интернет-приложений. Однако построение законченного web-приложения с использованием технологии Windows DNA (Distributed iNternet Architecture - распределенная межсетевая архитектура) до сих пор остается весьма сложной задачей.
      Значительная часть сложностей возникает оттого, что Windows DNA требует использования разнородных технологий и языков (ASP, HTML, XML, JavaScript, VBScript, COM(+), ADO и т. д.). Одна из проблем заключается в том, что синтаксически все эти языки и технологии очень мало похожи друг на друга. Например, синтаксис JavaScript больше похож на синтаксис C, в то время как VBScript является подмножеством Visual Basic. COM-серверы, предназначенные для работы в среде выполнения COM+, созданы на основе совершенно иных подходов, нежели ASP-страницы, которые к ним обращаются. Конечным результатом является пугающее см
      ешение технологий. Помимо всего прочего, в каждом языке, который входит в состав Windows DNA, предусмотрена своя система типов, что также не является источником большой радости для программистов. Например, тип данных int в JavaScript - это не то же самое, что int в C, который, в свою очередь, отличен от integer в Visual Basic.
      Решение .NET
      На этом мы будем считать обращение к новейшей истории программирования законченным. Главный вывод, с которым вряд ли кто-нибудь будет спорить, таков: тяжела жизнь Windows-программиста. На этом фоне возможности, предлагаемые платформой .NET, позволяют радикально облегчить нашу жизнь. Один из главных принципов .NET звучит так: "Изменяйте все, что хотите, откуда вам угодно". .NET - это совершенно новая модель для создания приложений под Windows (а в будущем, видимо, и под другими операционными системами). Вот краткое перечисление основных возможностей .NET:
      Полные возможности взаимодействия с существующим кодом. Вряд ли кто-нибудь будет спорить, что это - вещь очень хорошая. Как мы увидим в главе 12, существующие двоичные компоненты COM отлично работают вместе с двоичными файлами .NET.
      Полное и абсолютное межъязыковое взаимодействие. В отличие от классического COM, в .NET поддерживаются межъязыковое наследование, межъязыковая обработка исключений и межъязыковая отладка.
      Общая среда выполнения для любых приложений .NET, вне зависимости от того, на каких языках они были созданы. Один из важных моментов при этом - то, что для всех языков используется один и тот же набор встроенных типов данных.
      Библиотека базовых классов, которая обеспечивает сокрытие всех сложностей, связанных с непосредственным использованием вызовов API, и предлагает целостную объектную модель для всех языков программирования, поддерживающих .NET.
      Про пугающую сложность COM можно забыть! IClassFactory, IUnknown, код IDL и проклятые VARIANT-совместимые типы данных (BSTR, SAFEARRAY и остальные) больше не встретятся вам в коде программ .NET.
      Действительное упрощение процесса развертывания приложения. В .NET нет необходимости регистрировать двойные типы в системном реестре. Более того, .NET позволяет разным версиям одного и того же модуля DLL мирно сосуществовать на одном компьютере.
      Строительные блоки .NET (CLR, CTS и CLS)
      Технологии CLR, CTS и CLS очень важны для понимания смысла платформы .NET. С точки зрения программиста .NET вполне можно рассматривать просто как новую среду выполнения и новую библиотеку базовых классов. Среда выполнения .NET как раз и обеспечивается с помощью Common Language Runtime (CLR, стандартная среда выполнения для языков). Главная роль CLR заключается в том, чтобы обнаруживать и загружать типы .NET и производить управление ими в соответствии с вашими командами. CLR берет на себя всю низкоуровневую работу - например, автоматическое управление памятью, межъязыковым взаимоде
      йствием, развертывание (с отслеживанием версий) различных двоичных библиотек.
      Еще один строительный блок платформы .NET - это Common Type System (CTS, стандартная система типов). CTS полностью описывает все типы данных, поддерживаемые средой выполнения, определяет, как одни типы данных могут взаимодействовать с другими и как они будут представлены в формате метаданных .NET (подробнее о метаданных будет рассказано ниже в этой главе).
      Важно понимать, что не во всех языках программирования .NET обязательно должны поддерживаться все типы данных, которые определены в CTS. Common Language Specification (CLS) - это набор правил, определяющих подмножество общих типов данных, в отношении которых гарантируется, что они безопасны при использовании во всех языках .NET. Если вы создаете типы .NET с использованием только тех возможностей, которые совместимы с CLS, тем самым вы сделаете их пригодными для любых языков .NET.
      Библиотека базовых классов .NET
      Помимо спецификаций CLR и CTS/CLS платформа .NET предоставляет в ваше распоряжение также библиотеку базовых классов, доступную из любого языка программирования .NET. Библиотека базовых классов не только прячет обычные низкоуровневые операции, такие как файловый ввод-вывод, обработка графики и взаимодействие с оборудованием компьютера, но и обеспечивает поддержку большого количества служб, используемых в современных приложениях.
      В качестве примера можно привести встроенные типы для обращения к базам данных, работы с XML, обеспечения безопасности при работе приложения, создания приложений для работы в Web (конечно, обеспечивается и поддержка обычных консольных и оконных приложений). С концептуальной точки зрения отношения между уровнем среды выполнения и библиотекой базовых классов .NET выглядят так, как показано на рис. 1.1.
      Преимущества C#
      Специально для платформы .NET Microsoft был разработан новый язык программирования C#. C# - это язык программирования, синтаксис которого очень похож на синтаксис Java (но не идентичен ему). Например, в C# (как в Java) определение класса состоит из одного файла (*.cs), в отличие от C++, где определение класса разбито на заголовок (*.h) и реализацию (*.cpp). Однако называть C# клоном Java было бы неверно. Как C#, так и Java основаны на синтаксических конструкциях C++. Если Java во многих отношениях можно назвать очищенной версией C++, то C# можно охарактеризовать как очищенную версию Java.
      Синтаксические конструкции C# унаследованы не только от C++, но и от Visual Basic. Например, в C#, как и в Visual Basic, используются свойства классов. Как C++, C# позволяет производить перегрузку операторов для созданных вами типов (Java не поддерживает ни ту, ни другую возможность). C# - это фактически гибрид разных языков. При этом C# синтаксически не менее (если не более) чист, чем Java, так же прост, как Visual Basic, и обладает практически той же мощью и гибкостью, что и C++. Подводя итоги, еще раз выделим основные особенности C#.
      Указатели больше не нужны! В программах на C#, как правило, нет необходимости в работе с ними (однако если вам это потребуется, пожалуйста, - возможности для работы с указателями в вашем распоряжении).
      Управление памятью производится автоматически.
      В C# предусмотрены встроенные синтаксические конструкции для работы с перечислениями, структурами и свойствами классов.
      В C# осталась возможность перегружать операторы, унаследованные от C++. При этом значительная часть возникавших при этом сложностей ликвидирована.
      Предусмотрена полная поддержка использования программных интерфейсов. Однако в отличие от классического COM применение интерфейсов - это не единственный способ работы с типами, используя различные двоичные модули. .NET позволяет передавать объекты (как ссылки или как значения) через границы программных модулей.
      Также предусмотрена полная поддержка аспектно-ориентированных программных технологий (таких как атрибуты). Это позволяет присваивать типам характеристики (что во многом напоминает COM IDL) для описания в будущем поведения данной сущности.
      Возможно, самое важное, что необходимо сказать про язык C#, - это то, что он генерирует код, предназначенный для выполнения только в среде выполнения .NET. Например, вы не сможете использовать C# для создания классического COM-сервера. Согласно терминологии Microsoft код, предназначенный для работы в среде выполнения .NET, - это управляемый код (managed code). Двоичный файл, который содержит управляемый файл, называется сборкой (assembly). Подробнее об этом будет сказано ниже.
      Языки программирования .NET
      Во время анонса платформы .NET на конференции 2000 Professional Developers Conference (PDC) докладчики называли фирмы, работающие над созданием .NET-версий своих компиляторов. На момент написания этой книги компиляторы для создания .NET-версий приложений разрабатывались более чем для 30 различных языков. Помимо четырех языков, поставляемых с Visual Studio.NET (C#, Visual Basic.NET, "Managed C++" и JScript.NET), ожидаются .NET-версии Smalltalk, COBOL, Pascal, Python, Perl и множества остальных известных языков программирования. Общая картина представлена на рис. 1.2.
      Может показаться смешным, но двоичные файлы .NET, для которых используются стандартные расширения DLL и EXE, по своему внутреннему содержанию не имеют абсолютно ничего общего с обычными исполняемыми файлами. Например, файлы DLL не предоставляют свои методы в распоряжение приложений на компьютере. В отличие от компонентов COM двоичные файлы .NET не описываются с помощью кода IDL и регистрируются в системном реестре. Однако, пожалуй, самое важное отличие заключается в том, что двоичные файлы .NET не содержат зависящих от платформы команд. Содержимое двоичных файлов .N
      ET - это платформенно-независимый "промежуточный язык", который официально называется Microsoft Intermediate Language (MSIL, промежуточный язык Microsoft), или просто IL.
      Обзор двоичных файлов .NET ("сборки")
      Когда с помощью компилятора для платформы .NET создается модуль DLL или EXE, содержимое этого модуля - это так называемая сборка (assembly) на языке IL. Мы будем рассматривать сборки более подробно в главе 6. Однако для того, чтобы лучше понять особенности среды выполнения .NET, нам потребуется охарактеризовать хотя бы некоторые базовые свойства этого нового формата исполняемых файлов.
      Как уже говорилось, сборка содержит код на "промежуточном языке" - IL. Назначение IL концептуально аналогично байт-коду Java - он компилируется в платформенно-специфичные инструкции, только когда это абсолютно необходимо. "Абсолютная необходимость" возникает тогда, когда к блоку инструкций IL (например, реализации метода) обращается для использования среда выполнения .NET.
      Помимо инструкций IL, двоичные модули .NET содержат также метаданные, которые подробно описывают все типы, использованные в модуле. Например, если у вас внутри сборки есть класс Foo, то в метаданных этой сборки будет содержаться информация о базовом классе для Foo, какие интерфейсы предусмотрены для Foo (если они вообще предусмотрены), а также полное описание всех методов, свойств и событий этого класса.
      Во многих отношениях метаданные .NET являются значительным усовершенствованием по сравнению с классической информацией о типах в COM. Классические двоичные файлы COM обычно описываются с помощью ассоциированной библиотеки типов (которая очень похожа на двоичную версию кода IDL). Проблема с информацией о типах в COM заключается в том, что никто не может гарантировать вам, что эта информация окажется полной. Код IDL не может создать полный каталог внешних серверов, которые могут быть необходимы для нормальной работы содержащихся в модуле COM классов. Существовани
      е метаданных .NET, напротив, обеспечивается тем, что метаданные автоматически генерируются компилятором, создающим приложение .NET.
      Метаданные описывают не только типы, используемые в сборке, но и саму сборку. Эта часть метаданных называется манифестом (manifest). В манифесте содержится информация о текущей версии сборки, об использованных ограничениях по безопасности, о поддерживаемом естественном языке (английском, русском и т. д.), а также список всех внешних сборок, которые потребуются для нормального выполнения. Нам предстоит рассмотреть в этой главе различные средства, которые можно использовать для анализа кода IL внутри сборки, метаданных для типов и манифеста.
      Сборки из одного и нескольких файлов
      В подавляющем большинстве случаев двоичный файл .NET и сборка - это одно и то же и между ними существует отношение "один-к-одному". Если мы будем говорить о создании .NET DLL, то понятия "двоичный файл" и "сборка" мы будем использовать как синонимы. Однако (подробнее об этом - в главе 6) такой подход верен не всегда. Сборка может состоять как из одного, так и из нескольких двоичных файлов. В сборке из одного файла (single file assembly) этот единственный файл содержит и манифест, и метаданные, и инструкции IL.
      В сборке из нескольких двоичных файлов (multifile assembly) каждый двоичный файл называется модулем (module). При создании таких многофайловых сборок один из двоичных файлов должен содержать манифест сборки (в нем могут также находиться и другие данные, в том числе инструкции IL). Все остальные модули могут содержать только метаданные типов и инструкции IL.
      Зачем может потребоваться создание многофайловой сборки? Единственная причина для этого - большая гибкость при развертывании приложения. Например, если пользователь обращается к удаленной сборке, которая должна быть загружена на его локальный компьютер, среда выполнения загрузит лишь те модули сборки, которые действительно необходимы. Такое решение позволит избежать ненужного сетевого трафика и увеличить скорость работы программы.
      Роль Microsoft Intermediate Language
      Теперь, когда вы уже имеете представление о сборках .NET, мы можем рассмотреть Microsoft Intermediate Language (IL) - промежуточный язык Microsoft, более подробно. Код IL не зависит от платформы, на которой будет производиться выполнение. При этом компилятор для платформы .NET сгенерирует код IL вне зависимости от того, какой язык программирования (C#, Visual Basic.NET, Eiffel и т. п.) вы использовали для создания программы. Пожалуй, есть смысл продемонстрировать это более наглядно. В качестве примера мы создадим не самый сложный калькулятор. Единственное, что он у нас будет уметь делать - произво
      дить сложение 10 и 84. Ниже приведен код этого калькулятора на С#. Пока можно не задумываться об особенностях синтаксиса в этом примере, но отметьте для себя код, относящийся к методу Add().
     
      // С пространствами имен мы познакомимся чуть ниже в этой главе
      namespace Calculator
      {
      using System;
     
      // В классе Calculator определен метод Add(), а также точка входа
      // приложения - метод Main()
      public class Calc
      {
      // Конструктор по умолчанию
      public Calc(){}
     
      public int Add(int x, int y)
      {
      return x + y;
      }
     
      public static int Main(string[] args)
      {
      // Создаем объект Calc и складываем два числа
      Calc c = new Calc();
      int ans = c.Add(10, 84);
      Console.WriteLine("10 + 84 is {0}.", ans);
      return 0;
      }
      }
      }
     
      После того как этот исходный файл будет обработан компилятором C# (csc.exe), в нашем распоряжении окажется исполняемый файл C# - сборка из одного файла. Внутри этого файла можно будет обнаружить манифест, инструкции IL и метаданные, описывающие класс Calc. Если мы заглянем внутрь этой сборки (с помощью чего - об этом мы скажем ближе к концу этой главы), то помимо всего прочего мы сможем найти следующий блок инструкций IL, относящихся к методу Add():
      .method public hidebysig instance int32 Add(int32 x, int32 y) il managed
     
      {
      // Размер кода 8 (0x8)
      .maxstack 2
      .locals ([0] int32 V_0)
      IL_0000: ldarg.1
      IL_0001: ldarg.2
      IL_0002: add
      IL_0003: stloc.0
      IL_0004: br.s IL_0006
      IL_0006: ldloc.0
      IL_0007: ret
      } // Конец кода IL для метода Calc:Add()
     
      Если большая часть строк в коде IL осталась для вас загадкой, не волнуйтесь. Код IL будет рассмотрен более подробно в главе 7. Пока самое важное - отметить, что компилятор C# генерирует не платформенно-зависимый набор инструкций, а код IL. То же самое справедливо и для других компиляторов .NET. Давайте создадим наш калькулятор на языке Visual Basic.NET:
     
      ' Калькулятор VB.NET
      Module Module1
      ' Опять-таки, в классе Calc определен метод Add()
      ' и точка входа для приложения
      Class Calc
     
      Public Function Add(ByVal x As Integer, ByVal y As Integer) As Integer
      ' Да! Теперь Visual Basic поддерживает ключевое слово 'return'
      Return x + y
      End function
      End Class
      Sub Main()
      Dim ans As Integer
      Dim c As New Calc()
      ans = c.Add(10, 84)
      Console.WriteLine("10 + 84 is {0}.", ans)
      End Sub
      End Module
      Если мы поищем внутри сборки код, относящийся к методу Add(), то мы сможем обнаружить следующее:
      .method public instance int32 Add(int32 x, int32 y) il managed
      {
      // Размер кода 11 (0xb)
      .maxstack 2
      .locals init ([0] int32 Add)
      IL_0000: nop
      IL_0001: ldarg.1
      IL_0002: ldarg.2
      IL_0003: add.ovf
      IL_0004: stloc.0
      IL_0005: nop
      IL_0006: br.s IL_0008
      IL_0008: nop
      IL_0009: ldloc.0
      IL_000a: ret
      } // Конец метода Module1$Calc::Add
     
      Как мы видим, получившийся код IL практически идентичен. Незначительные отличия возникают вследствие особенностей компиляторов C# и Visual Basic.NET.
      Код приложений CSharpCalculator и VBCalculator можно найти в подкаталоге Chapter 1.
      Преимущества IL
      Возможно, к этому времени у вас уже созрел вопрос - а в чем, собственно, вообще могут состоять преимущества IL перед обычным набором платформенно-зависимых инструкций? Одно из преимуществ, про которое мы уже говорили, - возможность полного межъязыкового взаимодействия. Поскольку любой код на любом языке программирования .NET компилируется в стандартный набор инструкций IL, проблем во взаимодействии между блоками кода IL не будет. При этом взаимодействие будет производиться, как и положено, на двоичном уровне.
      Еще одно возможное преимущество - потенциальная независимость от компьютерной платформы. Существует большая вероятность, что среда выполнения .NET будет распространена на самые разные компьютерные платформы и операционные системы (отличные от Windows). В результате .NET может пойти по стопам Java - то есть с помощью языков .NET можно будет создавать программы, которые будут работать под самыми разными операционными системами (и при этом в отличие от Java еще и пользоваться преимуществами языковой независимости!) Таким образом, .NET потенциально позволяет создавать п
      риложения на любом языке, которые будут работать на любой платформе и под любой операционной системой.
      Однако в отношении межплатформенности пока ключевое слово - "потенциально". На момент создания этой книги Microsoft официально не произнесла ни слова относительно возможности портирования среды выполнения .NET под другие операционные системы. Поэтому пока мы будем считать, что приложения .NET работают только под Windows.
      Роль метаданных
      Программистам, работающим с COM, хорошо знакома концепция Interface Definition Language (IDL, языка определения интерфейсов). IDL - это "метаязык", который позволяет, исключив любую двусмысленность, описать типы, используемые внутри сервера COM. IDL компилируется в двоичный формат (называемый библиотекой типов) с использованием компилятора midl.exe. Этот компилятор может использоваться любым языком, предназначенным для работы с COM.
      IDL полностью описывает все типы данных, используемые в двоичном файле COM, но информация о самом этом двоичном файле в нем минимальна. Фактически она ограничивается номером версии (к примеру, 1.0, 2.0 или 2.4) и информацией о локализации (например, English, German, Russian). Кроме того, наличие или отсутствие метаданных (и их полноту) должен вручную контролировать создающий сервер COM программист - таким образом, необходимых метаданных в двоичном файле COM может вообще не оказаться.
      В отличие от COM при использовании платформы .NET вам вообще не придется думать об IDL. Однако общий принцип описания типов в строго определенном двоичном формате остался.
      Сборки .NET всегда содержат полные и точные метаданные, поскольку метаданные в них генерируются автоматически. Как и в IDL, в метаданных .NET содержится исчерпывающая информация об абсолютно всех типах, которые используются в сборке (классах, структурах, перечислениях и прочем), а также о каждом свойстве, методе или событии каждого типа.
      Еще одно отличие метаданных .NET от информации IDL заключается в том, что метаданные .NET гораздо более подробны. В них перечислены все ссылки на внешние модули и сборки, которые потребуются для нормального выполнения сборки .NET. За счет этого можно считать сборки .NET фактически самодокументируемыми. В результате, к примеру, отпадает необходимость регистрировать двоичные файлы .NET в системном реестре (подробнее об этом будет сказано ниже).
      Простой пример метаданных
      Вот пример метаданных для метода Add() нашего приложения CSharpCalculator (метаданные для этого метода в VBCalculator будут точно такими же):
     
      Method #2
      ___________________________
      MethodName : Add (06000002)
      Flags : [Public] [HideBySig] [ReuseSlot] (00000086)
      RVA : 0x00002058
      ImplFlags : [IL] [Managed] (00000000)
      CalcCnvntn : [DEFAULT]
      hasThis
      ReturnType : I4
      2 Arguments
      Argument #1: I4
      Argument #2: I4
      2 Parameters
      (1) ParamToken : (08000001) Name : x flags: [none] (00000000) default:
      (2) ParamToken : (08000002) Name : y flags: [none] (00000000) default:
     
      В коде ясно представлены название метода, тип возвращаемого значения и данные об ожидаемых аргументах. Как мы помним, вручную никаких метаданных мы не писали - за нас все сделал компилятор C#.
      Кто будет обращаться к метаданным? И сама среда выполнения .NET (очень часто), и самые разные средства разработки и отладки. Например, средство IntelliSense в Visual Studio.Net (которое пытается помочь вам закончить начатую строку) берет необходимую ему информацию именно из метаданных. Метаданные активно используются утилитами просмотра, отладки и, конечно, самим компилятором C#.
      Компиляция IL в платформенно-зависимые инструкции
      Поскольку в сборках, как мы выяснили, содержится платформенно-независимый код IL, а выполняются в конечном итоге именно платформенно-зависимые инструкции, кто-то должен взять на себя работу по компиляции IL в такие инструкции. Этот "кто-то" называется "just-in-time compiler" (JIT) - компилятор времени выполнения. JIT часто ласково называют "jitter" (дрожание, трепет). JIT для перевода IL в платформенно-зависимые инструкции входит в состав среды выполнения .NET. Используя код IL, разработчики могут не думать об особенностях архитектуры CPU данного компьютера - эти особенности будут у
      чтены JIT.
      Откомпилированные из IL платформенно-зависимые инструкции JIT помещает в кэш-памяти, что очень сильно ускоряет работу приложения. Предположим, был вызван метод Bar() класса Foo. При первом вызове этого метода JIT откомпилирует относящийся к этому методу код IL в платформенно-зависимые инструкции. При повторных вызовах этого метода JIT уже не будет заниматься компиляцией, а просто возьмет уже готовый откомпилированный код из кэша в оперативной памяти.
      Типы .NET и пространства имен .NET
      Сборка (не важно, однофайловая или многофайловая) может содержать любое количество самых разных типов. В мире .NET тип - это общий термин, который может относиться к классам, структурам, интерфейсам, перечислениям и прочему. При создании приложения .NET (например, на языке C#) вам потребуется организовывать взаимодействие этих типов. Например, сборка может определять класс с несколькими интерфейсами; один интерфейс может принимать в качестве параметров только значения определенного перечисления.
      У вас есть возможность использовать пространства имен при создании ваших собственных типов. Пространство имен - это логическая структура для организации имен, используемых в приложении .NET. Основное назначение пространств имен - предупредить возможные конфликты между именами в разных сборках.
      Вот пример: вы создаете приложение типа Windows Forms, которое обращается к двум внешним сборкам. В каждой сборке есть тип с именем GoCart, при этом эти типы отличаются друг от друга. При написании кода вы можете точно указать, к какому именно типу и из какой сборки вы обращаетесь. Для этого достаточно к имени типа добавить имя соответствующего пространства имен: например, CustomVehicals.GoCart или SlowVehicals.GoCart. Более подробно мы разберем применение пространств имен ниже в этой главе.
      Основы Common Language Runtime - среды выполнения .NET
      После того как мы познакомились с типами, сборками, метаданными и IL, настало время рассмотреть среду выполнения .NET - CLR более подробно. Среду выполнения (runtime) можно рассматривать как набор служб, необходимых для работы блока программного кода. К таким службам можно отнести и требуемые библиотеки. Например, если вы создали приложение MFC, то в качестве компонента среды выполнения вам потребуется весьма объемистая библиотека времени выполнения Microsoft Foundation Classes - mfc42.dll. Программы на Visual Basic привязаны к такому компоненту среды выполнения, как библиотека msvbvm60.dll,
      а программам на Java необходим большой набор файлов, входящих в состав виртуальной машины Java.
      Своя среда выполнения требуется и приложениям .NET. Главное отличие этой среды выполнения от всех тех, которые были перечислены выше, заключается в том, что единая среда выполнения .NET используется приложениями, написанными на любых языках программирования .NET. Как уже говорилось выше, среда выполнения .NET носит официальное название Common Language Runtime (CLR).
      Сама CLR состоит из двух главных компонентов. Первый компонент - это ядро среды выполнения, которое реализовано в виде библиотеки mscoree.dll. При обращении к приложению .NET mscoree.dll автоматически загружается в память, и, в свою очередь, эта библиотека управляет процессом загрузки в память сборки данного приложения. Ядро среды выполнения ответственно за множество задач. Оно занимается поиском физического местонахождения сборки, обнаружением внутри сборки запрошенного типа (класса, интерфейса, структуры и т. п.) на основе информации метаданных, компилирует IL в пла
      тформенно-зависимые инструкции, выполняет проверки, связанные с обеспечением безопасности, - и этот перечень далеко не полон.
      Второй главный компонент CLR - это библиотека базовых классов. Сама библиотека разбита на множество отдельных сборок, однако главная сборка библиотеки базовых классов представлена файлом mscorlib.dll. В библиотеке базовых классов содержится огромное количество типов для решения распространенных задач при создании приложения. Приложение .NET будет обязательно использовать сборку mscorlib.dll и по мере необходимости - другие сборки (как встроенные, так и создаваемые вами самими).
      На рис. 1.3 представлен путь, который проходит исходный код приложения, прежде чем воплотиться в выполнение каких-либо действий на компьютере.
      Стандартная система типов CTS
      Мы уже говорили, что стандартная система типов (Common Type System, CTS) - это формальная спецификация, которая определяет, как какой-либо тип (класс, структура, интерфейс, встроенный тип данных и т. п.) должен быть определен для его правильного восприятия средой выполнения .NET. CTS определяет синтаксические конструкции (в качестве примера можно взять перегрузку операторов), которые могут поддерживаться, а могут и не поддерживаться конкретным языком программирования .NET. Если вы хотите создавать сборки, которые смогут использоваться всеми языками программирования .NET,
      вам придется при создании типов следовать правилам Common Language Specification - CLS. А сейчас мы рассмотрим особенности тех типов, к которым применяется спецификация CTS.
      Классы CTS
      Концепция классов - краеугольный камень любого объектно-ориентированного программирования. Она поддерживается всеми языками программирования .NET. Класс (class) - это набор свойств, методов и событий, объединенных в единое целое. Как, наверное, вы и предполагали, в CTS предусмотрены абстрактные члены классов, что обеспечивает возможность применения полиморфизма в производных классах. Множественное наследование в CTS запрещено. Самые важные характеристики классов представлены в табл. 1.1.
      Таблица 1.1. Самые важные характеристики классов CTS
     
      Характеристика Ее смысл
      Является ли класс "закрытым"? Закрытые классы не могут становиться базовыми для других классов
      Предусмотрены ли в классе какие-либо интерфейсы? Интерфейс - это набор абстрактных членов, который обеспечивает связь между объектом и пользователем. В CTS в классе может быть любое количество интерфейсов
      Является ли класс абстрактным? Объекты абстрактных классов создать невозможно. Единственное назначение абстрактных классов - выполнять роль базовых для других классов. За счет механизма наследования абстрактные классы обеспечивают производные классы общими наборами членов
      Какова область видимости для данного класса? Для каждого класса должен быть определен атрибут области видимости (visibility). Как правило, значение этого атрибута определяет, можно ли обращаться к этому классу из внешних сборок или только из той, которая его содержит
      Структуры CTS
      Помимо классов в CTS также предусмотрена концепция структур (structures). Если вы работали с C, возможно, вы удивитесь, что этот пользовательский тип данных сохранился и в мире .NET (правда, надо отметить, что он немного изменился). В принципе, структуры можно грубо рассматривать как упрощенные разновидности классов (подробнее о различиях между классами и структурами будет рассказано в главе 2). Структуры CTS могут иметь любое количество конструкторов с параметрами (конструктор без параметров зарезервирован). С помощью конструкторов с параметрами вы можете установ
      ить значение любого поля объекта структуры в момент создания этого объекта. Например:
     
      // Определяем структуру C#
      struct Baby
      {
      // В структуре могут быть поля:
      public string name;
      // В структуре можно определить конструкторы (но только c параметрами):
      public Baby (string name)
      {this.name = name; }
     
      // В структурах могут быть определены методы:
      public void Cry()
      { Console.WriteLine ("Waaaaaaaaaaah!!!"); }
     
      public bool IsSpleeping() { return false; }
      public bool IsChanged() { return false; }
      }
     
      А вот наша структура в действии:
     
      // Добро пожаловать в мир малютки Макса!
     
      Baby barnaBaby = new Baby ("Max");
      Console.WriteLine ("Changed?: {0}", barnaBaby.IsChanged().ToString());
     
      Console.WriteLine ("Sleeping?: {0}", barnaBaby.IsSleeping().ToString());
     
      // А теперь Макс покажет нам свою подлинную сущность:
      for(int i=0; i<10000; i++)
      barnaBaby.Cry();
      Все CTS-совместимые структуры произведены от единого базового класса System.ValueType. Этот базовый класс определяет структуру как тип данных для работы только со значениями, но не с ссылками. В структуре может быть любое количество интерфейсов. Однако структуры не могут быть унаследованы от остальных типов данных и они всегда являются "закрытыми" - то есть они не могут выступать в качестве базовых для целей наследования.
      Интерфейсы CTS
      Интерфейсы (interfaces) - это просто наборы абстрактных методов, свойств и определений событий. В отличие от классической технологии COM, интерфейсы .NET не являются производными от единого общего интерфейса, каким в мире COM был интерфейс IUnknown. В интерфейсах самих по себе смысла не очень много. Однако если мы знаем, что какой-либо класс реализует известный нам интерфейс, мы вправе требовать от этого класса определенной функциональности. При создании своего собственного интерфейса на .NET-совместимом языке программирования вы можете произвести этот интерфейс сраз
      у от нескольких базовых интерфейсов. Подробнее про использование интерфейсов в программах на C# будет рассказано в главе 6.
      Члены типов CTS
      Как мы уже говорили, в классах и структурах может быть любое количество членов. Член (member) - это либо метод, либо свойство, либо поле, либо событие. Подробнее про члены типов в мире .NET будет рассказано в нескольких ближайших главах. Однако нам сейчас важно отметить, что для любого члена в .NET существует набор характеристик.
      Например, любой член в .NET характеризуется своей областью видимости (public, private, protected и т. д.). Член можно объявить как абстрактный, чтобы воспользоваться возможностями полиморфизма при работе с производными классами. Члены могут быть статическими (static, такие члены могут совместно использоваться всеми объектами данного класса) и обычными - принадлежащими только одному объекту данного класса.
      Перечисления CTS
      Перечисление (enumeration) - это удобная программная конструкция, которая позволяет вам объединять пары имя - значение под указанным вами именем перечисления. Предположим, что вы создаете компьютерную игрушку, в которой играющий сможет выбирать из трех типов персонажей - волшебника (Wizard), воина (Fighter) или вора (Thief). В этой ситуации очень удобно будет воспользоваться перечислением:
      // Перечисление C#:
      enum PlayerType
      { Wizard=100, Fighter=200, Thief=300 };
      В CTS все перечисления являются производными от единственного базового класса System.Enum. Как мы убедимся в будущем, этот базовый класс содержит множество полезных членов, которые помогут нам в извлечении (и выполнении прочих операций) с парами имя - значение.
      Делегаты CTS
      Делегаты (delegates) - в мире .NET это безопасный для типов эквивалент указателя на функцию в C. Однако между ними есть и существенное отличие. Делегат .NET - это уже не просто адрес в оперативной памяти, а класс, производный от базового класса MulticastDelegate. Делегаты очень полезны в тех ситуациях, когда вам нужно, чтобы одна сущность передала вызов другой сущности. Делегаты - это краеугольный камень в технологии обработки событий .NET (об этом - в главе 5).
      Встроенные типы данных CTS
      Конечно же, в .NET предусмотрен богатый набор встроенных типов данных. Помимо всего прочего, этот набор еще и един для всех языков программирования .NET. Названия типов данных в языках .NET могут выглядеть по-разному, но эти названия - всего лишь псевдонимы для встроенных системных типов данных .NET, определенных в библиотеке базовых типов. Перечень встроенных типов данных .NET представлен в табл. 1.2.
      Таблица 1.2. Встроенные типы данных CTS
     
      Встроенный тип данных .NET Название в Visual Basic.NET Название в C# Название в Managed C++
      System.Byte Byte byte char
      System.SByte Не поддерживается sbyte signed char
      System.Int16 Short short short
      System.Int32 Integer int int или long
      System.Int64 Long long _int64
      System.UInt16 Не поддерживается ushort unsigned short
      System.UInt32 Не поддерживается uint unsigned int или unsigned long
      System.UInt64 Не поддерживается ulong unsigned _int64
      System.Single Single float float
      System.Double Double double double
      System.Object Object object Object*
      System.Char Char char _wchar_t
      System.String String string String*
      System.Decimal Decimal decimal Decimal
      System.Boolean Boolean bool bool
      Как видно из таблицы, не все языки .NET могут работать с некоторыми встроенными типами данных CTS. Поэтому очень важно определить такой набор типов (и программных конструкций), с которым гарантированно смогут работать любые .NET-совместимые языки программирования. Такой набор есть, и он называется CLS.
      Основы CLS
      Нет необходимости доказывать, что одни и те же программные конструкции в разных языках выглядят абсолютно по-разному. Например, в C# объединение строк (конкатенация) производится с помощью оператора плюс (+), в то время как в Visual Basic для этой же цели используется амперсанд (&). А вот как выглядит в разных языках функция, не возвращающая значений:
      ' Функция (подпроцедура) VBasic, которая ничего не
      ' возвращает (возвращает значение типа void):
     
      Public Sub Foo()
      ' Что-то делаем...
      End Sub
     
      // Такая же функция в C#:
      public void Foo()
      {
      // Делаем то же самое...
      }
     
      Как мы уже видели, для среды выполнения .NET такая разница в синтаксисе абсолютно безразлична: все равно соответствующие компиляторы (в нашем случае vbc.exe и csc.exe) создадут одинаковый код IL. Однако языки программирования отличаются не только синтаксисом, но и возможностями. Например, в одних языках программирования разрешена перегрузка операторов, а в других - нет. Одни языки могут использовать беззнаковые (unsigned) типы данных, а в других такие типы данных не предусмотрены. Вывод очевиден - нам нужны некие единые правила для всех языков .NET. Если мы им следуем, то
      гарантируется, что программные модули, написанные на разных языках, будут нормально взаимодействовать друг с другом. Такой набор правил определен в спецификации CLS (Common Language Specification).
      Набор правил, определяемый CLS, не только гарантирует нормальное взаимодействие блоков кода, созданных на разных языках. Такой набор правил еще и определяет минимальные требования, которые предъявляются к любому .NET-совместимому компилятору. Необходимо помнить, что в CLS - это лишь часть тех возможностей, которые определены в CTS.
      Правилам CLS должны удовлетворять и инструментальные средства среды разработки - если мы хотим обеспечить межъязыковое взаимодействие, они должны генерировать только такой код, который соответствует требованиям CLS. У каждого правила CLS есть простое название (например, CLS Rule 6 - правило CLS номер 6). Вот пример одного из правил (это самое важное правило - правило номер 1):
      Правило 1. Правила CLS относятся только к тем частям типа, которые предназначены для взаимодействия за пределами сборки, в которой они определены.
      Из этого правила явствует, что во внутренней логике при реализации какого-либо типа вы можете сколько угодно нарушать правила CLS - это ни на что не повлияет. Например, предположим, что вы создаете приложение .NET, которое взаимодействует с внешним миром с помощью трех классов, а в каждом из этих классов есть только одна функция. Правилам CLS в этом случае должны удовлетворять только три этих функции-члена (в отношении области видимости, соглашений об именовании, типов принимаемых параметров и т. д.). Во внутренней реализации этих функций, классов или приложения
      в целом может быть сколько угодно отступлений от правил CLS - за пределами вашего программного модуля никто об этом никогда не узнает.
      Конечно, в CLS существует не только правило 1, но и множество других правил. В CLS, к примеру, строгие требования предъявлены к представлению символьных значений, к определению перечислений, к использованию статических членов и т. д. Однако заучивать эти правила совершенно не обязательно (конечно, если вы не заняты созданием .NET-совместимого компилятора для своего собственного языка программирования). Если вам потребовалась дополнительная информация по CLS, произведите поиск в MSDN по словосочетанию "Collected CLS Rules".
      Работа с пространствами имен
      Мы закончили обзор среды выполнения .NET и теперь обратимся к особенностям библиотеки базовых классов .NET. Важность библиотек кода очевидна. Например, библиотека MFC определяет набор классов C++ для создания диалоговых окон, меню и панелей управления. В результате программисты могут не заниматься изобретением того, что давным-давно уже сделано до них, а сосредоточиться на уникальных аспектах создаваемого ими приложения. Аналогичные средства существуют и в Visual Basic, и в Java, и во всех остальных языках программирования.
      Однако в отличие от MFC, Visual Basic и Java в C# не существует библиотеки базовых классов только для этого языка. Можно сказать, что библиотека базовых классов C# вообще не существует. Вместо этого разработчики на C# используют библиотеку базовых типов для всей среды .NET. А для лучшей организации типов внутри этой библиотеки используется концепция пространств имен.
      Главное отличие от библиотек, привязанных к конкретному языку (типа MFC), заключается в том, что в любом .NET-совместимом языке используются те же самые типы и те же самые пространства имен, что и в C#. Вот три приложения (весьма напоминающих классическое Hello, World) на трех разных .NET-совместимых языках: C#, VB.NET и Managed C++ (MC++).
     
      // Привет от C#
      using System;
      public class MyApp
      {
      public static void Main()
      {
      Console.WriteLine ("Hi from C#");
      }
      }
     
      ' Привет от VB.NET
      Imports System
      Public Module MyApp
     
      Sub Main()
      Console.WriteLine ("Hi from VB");
      End Sub
      End Module
     
      // Привет от Managed C++
      using namespace System;
      // Обратите внимание! Среда выполнения .NET в C++ сама собой помещает глобальную
      // функцию main внутрь определения класса
      void main()
      {
      Console::WriteLine("Hi from MC++");
      }
     
      Обратите внимание, что если нужен класс Console, то в любом языке .NET используется одно и то же пространство имен System. Если не обращать внимания на синтаксические различия, то код приложений на разных языках .NET практически идентичен. Платформе .NET свойственно изящество единого стиля программирования.
      Важнейшие пространства имен .NET
      Эффективность работы программиста, использующего .NET, напрямую зависит от того, насколько он знаком с тем массивом типов, который определен в пространствах имен библиотеки базовых классов. Самое важное пространство имен в C# - это System. В нем определены классы, которые обеспечивают самые важные функции C#. Вам не удастся создать ни одно работоспособное приложение C# без использования этого пространства имен.
      Пространство имен - это просто способ организации типов (классов, перечислений, интерфейсов, делегатов и структур) в единую группу. Конечно, обычно в одном пространстве имен объединяются взаимосвязанные типы. Например, тип System.Drawing содержит набор типов, которые призваны помочь вам в организации вывода изображений на графическое устройство. В .NET предусмотрены пространства имен для организации типов для работы с базами данными, Web, многопоточностью, защитой данных и множества других задач. В табл. 1.3 приведены некоторые (далеко не все) пространства имен .NET.
     
      Таблица 1.3. Пример пространства имен .NET
     
      Пространство имен .NET Назначение
      System Внутри - множество низкоуровневых классов для работы с простыми типами, выполнения математических операций, сборки мусора и т. п.
      System.Collections Для работы с контейнерными объектами, такими как ArrayList, Queue, SortedList
      System.Data Для обращений к базам данных. В книге этой теме посвящена
      System.Data.Common, System.Data.OleDb, System.Data.SqlClient специальная глава
      System.Diagnostics В этом пространстве имен содержатся многочисленные типы, используемые .NET-совместимыми языками для трассировки и отладки программного кода
      System.Drawing Типы для примитивов GDI+ - растровых изображений,
      System.Drawing.Drawing2D шрифтов, значков, поддержи печати. Предусмотрены также
      System.Drawing.Printing специальные классы для вывода более сложных изображений
      System.IO Как следует из названия, в этом пространстве имен объединены типы, отвечающие за операции ввода-вывода - в файл, буфер и т. п.
      System.Net Это пространство имен (как и все остальные, связанные с ним) содержит типы, относящиеся к передаче данных по сети (запрос - ответ, создание сокетов и т. п.)
      System.Reflection Классы, предназначенные для обнаружения, создания и вызова
      System.Reflection.Emit во время выполнения пользовательских типов
      System.Runtime.InteropServices Средства для взаимодействия с "традиционным" кодом
      System.Runtime.Remoting (Win32 DLL, COM-серверы) и типы, используемые для удаленного доступа (например, по коммутируемым соединениям)
      System.Security В мире .NET средства обеспечения безопасности интегрированы как со средой выполнения, так и с библиотекой базовых типов. В этом пространстве имен находятся классы для работы с разрешениями, криптографией и т. п.
      System.Threading Скорее всего, вы уже угадали - это пространство имен для типов, которые используются при работе с потоками (например, Mutex, Thread или Timeout)
      System.Web Классы, которые предназначены для использования в web-приложениях, включая ASP.NET
      System.Windows.Forms Классы для работы с элементами интерфейса Windows - окнами, элементами управления и прочим
      System.XML Множество классов для работы с данными в формате XML
      Использование пространств имен в коде приложения
      Как мы помним, пространство имен - это средство для логической группировки типов. С человеческой точки зрения выражение System.Console означает тип Console в пространстве имен System. Однако с точки зрения среды выполнения .NET System.Console - это единая сущность, к которой можно обратиться разными способами.
      Слово using нужно только вам - так проще будет обращаться к типам в конкретном пространстве имен. Если по каким-либо причинам использовать слово using вы не хотите, вполне можно обойтись и без него. Давайте рассмотрим это на примере. Предположим, что вы создаете обычное оконное приложение Windows, которое должно представлять на круговой диаграмме информацию, извлекаемую из базы данных. Кроме того, вам еще нужно поместить на главную форму своего приложения растровый рисунок с логотипом компании. Немного подумав, мы можем определить, что в нашем приложении нам потр
      ебуются классы из следующих пространств имен:
      //Пространства имен для использования в нашем приложении
      using System; //Без главного пространства имен не обойтись
      using System.Drawing; //для вывода изображений
      using System.Windows.Forms; //для элементов интерфейса
      using System.Data; //для доступа к базе данных using System.OleDb; //если к базе данных мы обращаемся по OLE DB
      После того как мы определим использование конкретного пространства имен (с использованием ключевого слова using), мы можем обращаться к типам, содержащимся в этом пространстве. Например, если нам потребовалось создать экземпляр класса Bitmap (определенном в пространстве имен System.Drawing), код может быть таким:
      //Явно указываем использование пространства имен:
     
      using System.Drawing;
     
      class MyClass
      {
      public void DoIt()
      {
      //Создаем растровое изображение 20 на 20 пикселов
      Bitmap bm = new Bitmap (20, 20);
      ...
      }
      }
     
      Поскольку мы явно указали использование пространства имен System.Drawing с помощью ключевого слова using, компилятор сможет понять, что класс Bitmap - это член данного пространства имен. Если в примере, приведенном выше, мы опустим строку со словом using, мы получим сообщение компилятора об ошибке. Однако можно обойтись и без using, если использовать полное имя класса, как в следующем примере:
      //Обратите внимание - никаких указаний на пространства имен!
     
      class MyClass
      {
      public void DoIt()
      {
      //Используем полное имя
      System.Drawing.Bitmap bm = new.System.Drawing.Bitmap (20, 20);
      ...
      }
      }
     
      Главная идея, я думаю, понятна: если вы явно указываете используемое пространство имен, строки при обращении к классам этого пространства имен получаются гораздо меньшего размера.
      Обращения к внешним сборкам
      Помимо того что вы можете явно указать используемое пространство имен с помощью ключевого слова using, иногда вам может потребоваться еще и явно указать физическое местонахождение сборки с необходимым кодом IL. Многие важнейшие пространства имен .NET физически связаны с файлом mscorlib.dll. Типы пространства имен System.Drawing физически "живут" внутри файла System.Drawing.dll. По умолчанию встроенные сборки .NET находятся в подкаталоге :\WINNT\Microsoft.NET\Framework\, как показано на рис. 1.4.
      В зависимости от того, какие средства разработки вы используете для создания приложений .NET, существует много способов сообщить компилятору, какие именно сборки вы собираетесь задействовать во время процесса компиляции. Про эти способы будет рассказано ниже.
      Если вам стало немного не по себе от мысли о том, сколько информации о пространствах имен и о типах вам придется осваивать, помните, что помнить все типы всех пространств имен совершенно незачем. Если вы создаете консольное приложение, вам можно забыть о всех типах System.Windows.Forms и System.Drawing (а, скорее всего, и о многих других). Если же вы разрабатываете редактор изображений, вам вряд ли потребуются интерфейсы для доступа к базам данных. Типы пространств имен можно осваивать постепенно, по мере необходимости.
      Как получить дополнительную информацию о пространствах имен и типах
      Во всех главах этой книги мы будем осваивать различные возможности платформы .NET, используя пространства имен и содержащиеся в них типы. Книга вряд ли стала бы лучше, если бы мы рассмотрели в ней все без исключения типы во всех встроенных пространствах имен. Вы должны уметь находить информацию о нужных вам типах и пространствах имен самостоятельно, тем более что инструментов для этой цели много. Вот их краткий перечень:
      документация .NET SDK (в MSDN);
      утилита ILDasm.exe;
      web-приложение ClassView;
      графическое приложение WinCV;
      ObjectBrowser, входящий в комплект Visual Studio.NET.
      Вряд ли вас нужно учить тому, как использовать MSDN (намекнем только, что внутри Visual Studio.NET можно попробовать начать с кнопки F1). А вот про все остальные утилиты стоит поговорить подробнее. Начнем с ILDasm.exe, ClassView и WinCV. Все эти утилиты поставляются вместе с .NET SDK.
      ILDasm.exe
      Официальное название ILDasm.exe звучит как Intermediate Language Disassembler utility (утилита дизассемблирования промежуточного языка). Эта утилита позволяет просмотреть содержимое любой сборки .NET (файла DLL или EXE) - ее манифест, метаданные типов и инструкции IL. При этом все операции производятся с использованием дружественного графического интерфейса. Просто запустите ILDasm.exe и через меню File 4 Open откройте нужную сборку. В порядке демонстрации мы откроем сборку mscorlib.dll (рис. 1.5). Путь к открытой нами сборке будет показан в заголовке окна ILDasm.
      Как мы видим, структура сборки представлена в самом обычном формате с деревом и узлами. Каждый метод, свойство, вложенный класс, как и все остальные типы, представлены специальными значками (в текстовом дампе дизассемблера эти значки будут заменены на аббревиатуры, состоящие из трех символов). Самые распространенные значки и соответствующие им аббревиатуры ILDasm приведены в табл. 1.4.
     

C# и платформа .NET. Библиотека программиста. / Э. Троелсен - СПб: Питер, 2003. - 800 с.

Экономика и управление | Право/a> | Бухгалтерский учет и налоги |