Система Orphus

CLR via C#. Программирование на платформе Microsoft .NET Framework 2.0 на языке C#

Автор: Джеффри Рихтер
Издательство: "Питер", "Русская Редакция", 2007
656 страниц
ISBN: 978-5-91180-303-2
ISBN: 5-7502-0285-2
ISBN: 0-7356-2163-2

Материал предоставил: Сергей Тепляков
Найти в магазинах

Аннотация

Содержание
Комментарии

Аннотация

Эта книга - подробное описание внутреннего устройства и функционирования общеязыковой исполняющей среды (CLR) Microsoft .NET Framework версии 2.0. В ней раскрыта система типов .NET Framework и разъяснены способы управления ими. Представлены концепции программирования с широким использованием библиотеки FCL, относящиеся ко всем языкам, ориентированным на работу с .NET Framework. Особое внимание уделено обобщениям, управлению асинхронными операциями и синхронизации потоков. Книга ориентирована на разработчиков любых видов приложений на платформе с .NET Framework: Windows Forms, Web Forms, Web-сервисов, консольных приложений и пр.

Книга состоит из 24 глав.

Содержание

Введение

Платформа разработки: .NET Framework
Среда разработки: Microsoft Visual Studio
Цель этой книги
Примеры кода и системные требования
В этой книге нет ошибок
Благодарности
Поддержка
Предисловие

Часть I Основы CLR

Глава 1 Модель выполнения кода в среде CLR

Компиляция исходного кода в управляемые модули
Объединение управляемых модулей в сборку
Загрузка CLR
Исполнение кода сборки
IL и верификация
Небезопасный код
IL и защита интеллектуальной собственности
NGen.exe - генератор объектного кода
Библиотека классов .NET Framework
Общая система типов
Общеязыковая спецификация
Взаимодействие с неуправляемым кодом

Глава 2 Компоновка, упаковка, развертывание и администрирование приложений и типов

Задачи развертывания в .NET Framework
Компоновка типов в модуль
Файл параметров
Несколько слов о метаданных
Объединение модулей для создания сборки
Добавление сборок в проект в среде Visual Studio
Использование утилиты Assembly Linker
Включение в сборку файлов ресурсов
Ресурсы со сведениями о версии сборки
Номера версии
Региональные стандарты
Развертывание простых приложений (закрытое развертывание сборок)
Простое средство администрирования (конфигурационный файл)

Глава 3 Совместно используемые сборки и сборки со строгим именем

Два вида сборок - два вида развертывания
Назначение сборке строгого имени
Глобальный кеш сборок
Внутренняя структура GAC
Компоновка сборки, ссылающейся на сборку со строгим именем
Устойчивость сборок со строгими именами к несанкционированной модификации
Отложенное подписание
Закрытое развертывание сборок со строгими именами
Как исполняющая среда разрешает ссылки на типы
Дополнительные административные средства (конфигурационные файлы)
Управление версиями при помощи политики издателя

Часть II Работаем с типами

Глава 4 Основы типов

Все типы - производные от System.Object
Приведение типов
Приведение типов в C# с помощью операторов is и as
Пространства имен и сборки
Как разные компоненты взаимодействуют во время выполнения

Глава 5 Элементарные, ссылочные и значимые типы

Элементарные типы в языках программирования
Проверяемые и непроверяемые операции для элементарных типов
Ссылочные и значимые типы
Упаковка и распаковка значимых типов
Изменение полей в упакованных размерных типах посредством интерфейсов
Равенство и тождество объектов
Хеш-коды объектов

Часть III Проектирование типов

Глава 6 Основные сведения о членах и типах

Члены типа
Видимость типа
Дружественные сборки
Доступ к членам
Статические классы
Частичные классы, структуры и интерфейсы
Компоненты, полиморфизм и версии
Вызов виртуальных методов, свойств и событий в CLR
Разумное использование видимости типов и модификаторов доступа к членам
Работа с виртуальными методами при управлении версиями типов

Глава 7 Константы и поля

Константы
Поля

Глава 8 Методы: конструкторы, операторы, преобразования и параметры

Конструкторы экземпляров и классы (ссылочные типы)
Конструкторы экземпляров и структуры (значимые типы)
Конструкторы типов
Производительность конструкторов типа
Методы перегруженных операторов
Операторы и взаимодействие языков программирования
Методы операторов преобразования
Передача методу параметров по ссылке
Передача методу переменного числа параметров
Объявление типов параметров метода
Методы-константы и параметры-константы

Глава 9 Свойства

Свойства без параметров
Осторожный подход к определению свойств
Свойства с параметрами
Производительность при вызове аксессоров свойств
Доступность аксессоров свойств
Обобщенные методы-аксессоры свойств

Глава 10 События

Проектирование типа, поддерживающего событие
Этап 1: определение типа, который будет хранить всю дополнительную информацию, передаваемую получателям уведомления о событии
Этап 2: определение члена-события
Этап 3: определение метода, ответственного за уведомление зарегистрированных объектов о событии
Этап 4: определение метода, транслирующего входную информацию в желаемое событие
Как реализуются события
Создание типа, отслеживающего событие
События и безопасность потоков
Явное управление регистрацией событий
Конструирование типа с множеством событий

Часть IV Важнейшие типы

Глава 11 Символы, строки и обработка текста

Символы
Тип System.String
Создание строк
Строки не изменяются
Сравнение строк
Интернирование строк
Создание пулов строк
Работа с символами и текстовыми элементами в строке
Прочие операции со строками
Эффективное создание строки динамически
Создание объекта StringBuilder
Члены StringBuilder
Получение строкового представления объекта
Форматы и региональные стандарты
Форматирование нескольких объектов в одну строку
Создание собственного средства форматирования
Получение объекта посредством разбора строки
Кодировки: преобразования между символами и байтами
Кодирование и декодирование потоков символов и байт
Кодирование и декодирование строк в кодировке Base-64
Защищенные строки

Глава 12 Перечислимые типы и битовые флаги

Перечислимые типы
Битовые флаги

Глава 13 Массивы

Приведение типов в массивах
Все массивы неявно наследуют классу System.Array
Все массивы неявно реализуют IEnumerable, ICollection и IList
Передача и возврат массивов
Создание массивов с ненулевой нижней границей
Производительность доступа к массиву
Небезопасный доступ к массивам и массивы фиксированного размера

Глава 14 Интерфейсы

Наследование в классах и интерфейсах
Определение интерфейсов
Наследование интерфейсов
Подробнее о вызовах интерфейсных методов
Явные и неявные реализации методов интерфейса (что происходит за кулисами)
Обобщенные интерфейсы
Обобщения и ограничение интерфейса
Реализация нескольких интерфейсов с одинаковыми сигнатурами и именами методов
Улучшение контроля типов при помощи явной реализации методов интерфейса
Осторожно с явной реализацией методов интерфейсов!
Дилемма проектировщика: базовый класс или интерфейс?

Глава 15 Делегаты

Знакомство с делегатами
Использование делегатов для обратного вызова статических методов
Использование делегатов для обратного вызова экземплярных методов
Правда о делегатах
Использование делегатов для обратного вызова множественных методов (цепочки делегатов)
Поддержка цепочек делегатов в C#
Расширенное управление цепочкой делегатов
Упрощение синтаксиса работы с делегатами в C#
Упрощенный синтаксис № 1: не нужно создавать объект-делегат
Упрощенный синтаксис № 2: не нужно определять метод обратного вызова
Упрощенный синтаксис № 3: не нужно определять параметры метода обратного вызова
Упрощенный синтаксис № 4: не нужно вручную создавать обертку локальных переменных класса для передачи их в метод обратного вызова
Делегаты и отражение

Глава 16 Обобщения

Обобщения в библиотеке FCL
Библиотека Power Collections от Wintellect
Инфраструктура обобщений
Открытые и закрытые типы
Обобщенные типы и наследование
Проблемы с идентификацией и тождеством обобщенных типов
"Распухание" кода
Обобщенные интерфейсы
Обобщенные делегаты
Обобщенные методы
Логический вывод обобщенных методов и типов
Обобщения и другие члены
Верификация и ограничения
Основные ограничения
Дополнительные ограничения
Ограничения конструктора
Другие вопросы верификации

Глава 17 Нестандартные атрибуты

Применение нестандартных атрибутов
Определение собственного класса атрибутов
Конструктор атрибута и типы данных полей/свойств
Обнаружение использования нестандартных атрибутов
Сравнение двух экземпляров атрибута
Обнаружение использования нестандартных атрибутов без создания объектов, производных от Attribute
Условные атрибутные классы

Глава 18 Значимые типы, допускающие присвоение null

Поддержка значимых типов, допускающих присвоение null, в C#
Оператор интеграции null в языке C#
CLR обеспечивает специальную поддержку значимых типов, допускающих присвоение null
Упаковка значимых типов, допускающих присвоение null
Распаковка значимых типов, допускающих присвоение null
Вызов GetType через значимый тип, допускающий присвоение null
Вызов интерфейсных методов через значимый тип, допускающий присвоение null

Часть V Средства CLR

Глава 19 Исключения

Эволюция обработки исключений
Механика обработки исключений
Блок try
Блок catch
Блок finally
Общеязыковая спецификация (CLS) и исключения, отличные от CLS-совместимых
Что же это такое - исключение?
Класс System.Exception
Классы исключений, определенные в FCL
Генерация исключений
Определение собственных классов исключений
Как правильно использовать исключения
Проверяйте аргументы своих методов
Блоков finally не должно быть слишком много
Не всякое исключение следует перехватывать
Корректное восстановление после исключения
Отмена незавершенных операций при невосстановимых исключениях
Сокрытие деталей реализации для сохранения контракта
Вопросы быстродействия
Необработанные исключения
Трассировка стека при исключениях
Отладка исключений

Глава 20 Автоматическое управление памятью (сбор мусора)

Основы работы платформы, поддерживающей сбор мусора
Выделение ресурсов из управляемой кучи
Алгоритм сбора мусора
Сбор мусора и отладка
Использование завершения для освобождения машинных ресурсов
Гарантированное завершение с использованием типов CriticalFinalizerObject
Тип SafeHandle и его производные
Взаимодействие с неуправляемым кодом с помощью типов SafeHandle
Применение завершения к управляемым ресурсам
Когда вызываются методы Finalize
Внутренний механизм завершения
Модель освобождения ресурсов: принудительная очистка объекта
Использование типов, поддерживающих модель освобождения ресурсов
Оператор using языка C#
Интересная проблема с зависимостью
Ручной мониторинг и управление временем жизни объектов
Воскрешение
Поколения
Другие возможности сборщика мусора по работе с машинными ресурсами
Прогнозирование успеха операции, требующей много памяти
Управление сборщиком мусора из программ
Другие вопросы производительности сборщика мусора
Выделение памяти без синхронизации
Масштабируемый параллельный сбор мусора
Параллельный сбор мусора
Большие объекты
Мониторинг сбора мусора

Глава 21 Хостинг CLR и домены приложения (AppDomains)

Хостинг CLR
Домены приложения
Доступ к объектам из другого AppDomain
Выгрузка доменов AppDomain
Как хосты используют домены AppDomain
Консольные приложения и приложения Windows Forms
Microsoft Internet Explorer
Web-формы ASP.NET и Web-сервисы XML
Microsoft SQL Server 2005
Будущее и мечты
Другие методы управления хостом
Управление CLR с помощью управляемого кода
Создание надежного приложения-хоста
Как поток возвращается в хост

Глава 22 Загрузка сборок и отражение

Загрузка сборок
Использование отражения для создания динамически расширяемых приложений
Производительность отражения
Обнаружение типов, определенных в сборке
Что же из себя представляет объект-тип
Создание иерархии типов, производных от Exception
Создание экземпляра типа
Создание приложений с поддержкой подключаемых компонентов
Использование отражения для обнаружения членов типа
Обнаружение членов типа
BindingFlags: фильтрация типов возвращаемых членов
Обнаружение интерфейсов типа
Вызов членов типа
Один раз привяжись, семь раз вызови
Использование описателей привязки для уменьшения рабочего набора

Глава 23 Асинхронные операции

Потоки Windows в CLR
К вопросу об эффективном использовании потоков
Пул потоков в CLR
Ограничение числа потоков в пуле
Использование пула потоков для выполнения асинхронных вычислительных операций
Использование выделенного потока для выполнения асинхронной операции
Периодическое выполнение асинхронной операции
История трех таймеров
Модель асинхронного программирования
Использование модели APM для выполнения асинхронного ввода-вывода
Три метода стыковки в модели APM
Стыковка с использованием ожидания завершения
Стыковка с использованием регулярного опроса
Стыковка путем обратного вызова метода
Использование модели APM для выполнения асинхронных вычислительных операций
Модель APM и исключения
Важные замечания о модели APM
Контексты выполнения

Глава 24 Синхронизация потоков

Целостность памяти, временный доступ к памяти и volatile-поля
Временная запись и чтение
Поддержка volatile-полей в C#
Семейство Interlocked-методов
Класс Monitor и блоки синхронизации
"Отличная" идея
Реализация "отличной" идеи
Использование класса Monitor для управления блоком синхронизации
Способ синхронизации, предлагаемый Microsoft
Упрощение кода C# при помощи оператора lock
Способ синхронизации статических членов, предлагаемый Microsoft
Почему же "отличная" идея оказалась такой неудачной
Знаменитый способ блокировки с двойной проверкой
Класс ReaderWriterLock
Использование объектов ядра Windows в управляемом коде
Вызов метода при освобождении одного объекта ядра

Комментарии

Сергей Тепляков

Книги Джеффри Рихтера не нуждаются в рекламе для большинства специалистов, которые более или менее серьезно занимаются программированием серверных приложений, программированием под Win32 или с использованием .NET Framework. Книги автора отличаются глубиной изложения материала. Автор никогда не пытается объять необъятное и описать все аспекты той или иной технологии. Но Рихтер умеет выделить главное и сосредоточиться на основополагающих вопросах и описать их с максимальной глубиной.

Книга начинается с описания модели выполнения кода в среде CLR, в которой автор рассказывает о том, что же такое CLR и касается основных вопросов ее функционирования, таких как загрузка CLR, JIT-компиляция, верификация, а также кратко рассматривается вопрос общей системы типов и общеязыковой спецификации. Далее автор уделяет значительное внимание развертыванию приложений и администрированию приложений и типов, включая сборки со строгими именами, глобальный кеш сборок (GAC), отложенное подписание и некоторые другие вопросы. Этот раздел является очень важным и полезным, но его достаточно сложно воспринять, если вы только начали знакомство с CLR. В таком случае его придется либо перетерпеть, либо пропустить и вернуться к нему несколько позже.

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

В третьей части автор рассматривает проектирование пользовательских типов данных. Понравился раздел об осторожном подходе к определению свойств, в котором автор описывает тонкие семантические различия между свойствами и методами с возвращаемым значением. Что несколько смутило в этой части, так это высказывания автора по поводу минимизации количества виртуальных методов и идею замкнутого (closed) класса. Аргументы достаточно весомы, но заявление столь авторитетного человека может привести к неправильному пониманию принципов проектирования молодыми разработчиками. Рихтер непревзойденный специалист по .NET, но все же, в вопросах объектно-ориентированного проектирования следует отдать предпочтение советам Бертрана Мейера и некоторых других авторов.

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

Интересно описаны делегаты, их внутренне устройство, цепочки делегатов, прямая и обратная ковариация, различные варианты упрощенного синтаксиса работы с делегатами в C# 2.0.

Не оставлены без внимания нововведения C# 2.0. Рассмотрен класс Nullable, а также поддержка значимых типов, допускающих присвоение null, в C# 2.0. Хорошо описаны обобщения, открытые и закрытые типы, "распухание" кода, логический вывод обобщенных методов и типов, ограничения. Интересным является упоминание о библиотеке Power Collections от Wintellect. Это часть библиотеки STL, переписанной на C# 2.0, включая контейнеры и алгоритмы. Конечно после выхода LINQ практическая польза от этой библиотеки небольшая, но она может послужить неплохим примером для разработчиков, которые сталкиваются с проблемами при создании собственных контейнеров или алгоритмов.

Очень подробно описано автоматическое управление памятью. Для меня это был один из наиболее интересных разделов книги. Раздел полезен для понимания работы одного из важнейших компонентов CLR. Детально описан алгоритм работы сборщика мусора, внутренний механизм завершения, воскрешение, поколения, типы GCHandle, SafeHandle и CriticalFinalizerObject. Полезным является раздел о принудительной очистке ресурсов и об использовании типов, поддерживающих модель освобождения ресурсов.

В книге тщательно описаны нестандартные атрибуты, исключения, загрузка сборок и отражение. Приведен пример создания приложений с поддержкой подключаемых компонентов (add-in). Хорошо описаны проблемы многопоточности. Рассмотрены вопросы асинхронного взаимодействия и пул потоков. Описаны средства синхронизации потоков. Раскритикована "отличная" идея синхронизации потоков (использование конструкции lock(this)), предложенная компанией Microsoft, и описаны способы решения этой проблемы.

Выводы можно сделать следующие. Это одна из лучших книг о платформе .Net на сегодняшний день. Однозначно must have и must read для всех, кто серьезно занимается разработкой под .NET Framework. Книга также будет полезна опытным разработчикам, которые переходят на платформу .Net и хотят разобраться в ее внутреннем устройстве.