- •1. C# и платформа .Net 7
- •2. Создание приложений .Net с использованием c# 38
- •3. Основы c# 71
- •4. Массивы, кортежи и строки 118
- •5. Классы и объекты 157
- •6. Перегрузка функций-членов класса 195
- •7. Наследование и полиморфизм 214
- •8. Обработка исключений 231
- •9. Интерфейсы, структуры и перечисления 255
- •10. Делегаты, события и лямбда-выражения 270
- •11. Обобщения 296
- •12. Коллекции, перечислители и итераторы 323
- •13. Время жизни объектов 370
- •1.C# и платформа .Net
- •1.1Становление c#
- •Язык c и api-интерфейс Windows
- •1.2Создание c#
- •Развитие c#
- •1.3Версии c#
- •1.4Связь c# со средой .Net Framework
- •Что нового в .Net Framework 4
- •1.5Общеязыковая исполняющая среда clr
- •1.6Общая система типов cts
- •1.7Общеязыковая спецификация cls
- •1.8Сборки
- •Приватные сборки
- •Разделяемые сборки
- •Однофайловые и многофайловые сборки
- •1.9Промежуточный язык cil
- •Утилита ildasm.Exe
- •1.10Классы и пространства имен Классы .Net Framework
- •Пространства имен
- •Роль корневого пространства Microsoft
- •1.11Общеязыковая инфраструктура cli
- •2.Создание приложений .Net с использованием c#
- •2.2Компилятор csc.Exe
- •Добавление ссылок на внешние сборки
- •Компиляция нескольких файлов исходного кода
- •Работа с ответными файлами в c#
- •2.3Типы приложений .Net
- •Создание приложений asp.Net
- •Возможности asp.Net
- •Элементы управления веб-сервера
- •Создание Windows-форм
- •Службы Windows
- •2.4Работа с Visual Studio 2010
- •2.5Создание проекта в VisualStudio 2010
- •2.6Изучение проекта и заполнение его кодом
- •2.7Компоновка проекта
- •2.8Отладка кода
- •2.9Рефакторинг кода
- •2.10Расширение кода
- •2.11Утилита Class Designer
- •2.12Интегрируемая система документации .Net Framework
- •3.Основы c#
- •3.1Основы ооп
- •3.2Простая программа на c#
- •3.3Комментарии
- •3.4Переменные
- •3.5Область видимости переменных, константы
- •3.6Типы данных
- •3.7Литералы
- •3.8Преобразования типов
- •3.9Арифметические операторы
- •3.10Операторы отношения и логические операторы
- •If (var1 & var2) Console.WriteLine("Данный текст не выведется");
- •3.11Оператор присваивания
- •3.12Поразрядные операторы
- •3.13Тернарный оператор
- •3.14Условные операторы
- •If (условие)
- •3.15Циклы for и while
- •3.16Циклы do while и foreach
- •3.17Операторы перехода
- •4.Массивы, кортежи и строки
- •4.1Массивы
- •4.2Многомерные массивы
- •4.3Ступенчатые (зубчатые) массивы
- •4.4Класс Array
- •4.5Создание динамического массива
- •4.6Массивы в качестве параметров
- •4.7Кортежи
- •4.8Строки
- •Построение строк
- •Постоянство строк
- •Работа со строками
- •Методы класса String
- •Методы работы со строками
- •Немного о сравнении строк в c#
- •4.9Класс StringBuilder
- •Методы класса StringBuilder
- •4.10Форматирующие строки
- •Спецификаторы формата для чисел
- •Спецификаторы формата для дат
- •4.11Регулярные выражения в c#
- •4.11.1Введение в регулярные выражения
- •Метасимволы, используемые в регулярных выражениях c#
- •4.11.2Использование регулярных выражений в c#
- •Структура перечисления RegexOptions
- •Метасимволы замены в регулярных выражениях c#
- •5.Классы и объекты
- •5.1Классы
- •Общая форма определения класса
- •Данные-члены
- •5.2Класс Object
- •5.2.1Методы System.Object
- •5.2.2Класс object как универсальный тип данных
- •5.3Создание объектов
- •5.3.1Переменные ссылочного типа и присваивание
- •5.3.2Инициализаторы объектов
- •5.4Методы
- •Объявление методов
- •Возврат из метода и возврат значения
- •Использование параметров
- •5.5Конструкторы
- •5.6Сборка мусора и деструкторы
- •Деструкторы
- •5.7Ключевое слово this
- •5.8Доступ к членам класса
- •Модификаторы доступа
- •Организация закрытого и открытого доступа
- •5.9Модификаторы параметров
- •Модификаторы параметров
- •5.9.1Модификатор ref
- •5.9.2Модификатор out
- •5.9.3Модификатор params
- •5.10Необязательные и именованные аргументы
- •5.10.1Необязательные аргументы
- •5.10.2Именованные аргументы
- •5.11Рекурсия
- •5.12Ключевое слово static
- •5.12.1Статические конструкторы
- •5.12.2Статические классы
- •5.13Индексаторы
- •5.13.1Одномерные индексаторы
- •5.13.2Многомерные индексаторы
- •5.14Свойства
- •Автоматически реализуемые свойства
- •5.15Модификаторы доступа в аксессорах
- •6.Перегрузка функций-членов класса
- •6.1Перегрузка методов
- •6.2Перегрузка конструкторов
- •6.3Перегрузка индексаторов
- •6.4Основы перегрузки операторов
- •6.4.1Перегрузка бинарных операторов
- •6.4.2Перегрузка унарных операторов
- •6.4.3Выполнение операций со встроенными в c# типами данных
- •6.5Перегрузка операторов отношения и операторов true - false
- •6.5.1Перегрузка операторов отношения
- •6.5.2Перегрузка операторов true и false
- •6.6Перегрузка логических операторов
- •6.6.1Перегрузка укороченных логических операторов
- •6.7Операторы преобразования
- •7.Наследование и полиморфизм
- •7.1Основы наследования
- •7.2Защищенный доступ и исключение наследования
- •7.2.1Организация защищенного доступа
- •7.2.2Ключевое слово sealed
- •7.2.3Диаграммы классов Visual Studio
- •7.3Конструкторы и наследование
- •7.4Наследование и сокрытие имен
- •Применение ключевого слова base для доступа к скрытому имени
- •7.5Ссылки на базовый класс и объекты производных классов
- •7.6Виртуальные методы, свойства и индексаторы
- •7.7Абстрактные классы
- •8.Обработка исключений
- •8.1Основы обработки исключений
- •8.1.1Роль обработки исключений в .Net
- •8.1.2Составляющие процесса обработки исключений в .Net
- •8.2Перехват исключений
- •8.3Класс Exception
- •8.4Конфигурирование состояния исключения
- •8.4.1Свойство TargetSite
- •8.4.2Свойство StackTrace
- •8.4.3Свойство HelpLink
- •8.4.4Свойство Data
- •8.5Исключения уровня системы и приложения
- •8.5.1Исключения уровня системы (System.SystemException)
- •8.5.2Исключения уровня приложения (System.ApplicationException)
- •8.5.3Создание специальных исключений
- •8.6Обработка многочисленных исключений
- •8.6.1Применение нескольких операторов catch
- •1 2 0 10 12 Индекс выходит за пределы
- •8.6.2Перехват всех исключений
- •8.6.3Вложение блоков try
- •8.7Операторы throw и finally
- •8.7.1Оператор throw
- •8.7.2Повторное генерирование исключений
- •8.7.3Использование блока finally
- •8.8Исключения, связанные с поврежденным состоянием (Corrupted State Exceptions)
- •8.9Ключевые слова checked и unchecked
- •9.Интерфейсы, структуры и перечисления
- •9.1Интерфейсы
- •9.2Интерфейсные ссылки
- •9.2.1Ключевое слово as
- •9.2.2Ключевое слово is
- •9.3Интерфейсные свойства и индексаторы
- •9.3.1Интерфейсные свойства
- •9.3.2Интерфейсные индексаторы
- •9.4Наследование интерфейсов
- •9.5Явная реализация интерфейса
- •9.6Структуры
- •Назначение структур
- •9.7Перечисления
- •10.Делегаты, события и лямбда-выражения
- •10.1Делегаты
- •10.1.1Определение типа делегата в c#
- •10.1.2Базовые классы System.MulticastDelegate и System.Delegate
- •10.2Групповой вызов и адресация делегируемых методов
- •10.2.1Групповое преобразование делегируемых методов
- •10.2.2Применение методов экземпляра в качестве делегатов
- •10.2.3Групповая адресация
- •10.3Ковариантность и контравариантность делегатов
- •10.5Анонимные методы
- •10.6Лямбда-выражения
- •10.6.1Одиночные лямбда-выражения
- •10.6.2Блочные лямбда-выражения
- •10.7События
- •10.8Аксессоры событий
- •10.9Обработка событий в среде .Net Framework
- •Void обработчик(object отправитель, EventArgs е)
- •11.Обобщения
- •11.1Обзор обобщений
- •Рекомендации по именованию
- •11.2Обобщенные классы
- •11.3Ограниченные типы
- •Связь между параметрами типа с помощью ограничений
- •11.4Ограниченные классы
- •11.5Ограниченные интерфейсы и конструкторы Применение ограничения на интерфейс
- •Применение ограничения new() на конструктор
- •11.6Ограничения ссылочного типа и типа значения
- •11.7Иерархии обобщенных классов
- •11.8Средства обобщений Значения по умолчанию
- •Статические члены
- •11.9Обобщенные методы
- •11.10Обобщенные структуры
- •11.11Обобщенные делегаты
- •11.12Обобщенные интерфейсы
- •Сравнение экземпляров параметра типа
- •11.13Модификация обобщенных методов
- •11.13.1Переопределение виртуальных методов в обобщенном классе
- •11.13.2Перегрузка методов с несколькими параметрами типа
- •11.14Ковариантность и контравариантность в обобщениях
- •11.14.1Применение ковариантности в обобщенном интерфейсе
- •11.14.2Применение контравариантности в обобщенном интерфейсе
- •12.Коллекции, перечислители и итераторы
- •12.1Краткий обзор коллекций
- •12.2Необобщенные коллекции
- •12.2.1Интерфейсы необобщенных коллекций
- •12.2.2Структура DictionaryEntry
- •12.2.3Классы необобщенных коллекций
- •12.3Обобщенные коллекции
- •12.3.1Интерфейсы обобщенных коллекций
- •12.3.3Классы обобщенных коллекций
- •12.4Класс ArrayList
- •12.5Класс Hashtable
- •12.10.1Тип ключа
- •12.13Битовые коллекции
- •12.13.1Класс BitArray
- •12.13.2Структура BitVector32
- •12.14Специальные и наблюдаемые коллекции
- •12.14.1Специальные коллекции
- •12.14.2Наблюдаемые коллекции
- •12.15Параллельные коллекции
- •12.16Реализация интерфейса iComparable
- •12.17Реализация интерфейса iComparer
- •12.18Перечислители
- •12.18.1Применение обычного перечислителя
- •12.18.2Применение перечислителя типа iDictionaryEnumerator
- •12.19Реализация интерфейсов iEnumerable и iEnumerator
- •12.20Итераторы
- •13.Время жизни объектов
- •13.1Базовые сведения о времени жизни объектов
- •Установка объектных ссылок в null
- •13.2Роль корневых элементов приложения
- •Поколения объектов
- •13.3Параллельная и фоновая сборка мусора Параллельная сборка мусора в версиях .Net 1.0 - .Net 3.5
- •Фоновая сборка мусора в версии .Net 4.0
- •13.5Финализируемые объекты
- •Переопределение System.Object.Finalize()
- •Описание процесса финализации
- •13.6Высвобождаемые объекты
- •Повторное использование ключевого слова using в c#
- •13.7Финализируемые и высвобождаемые типы
- •Формализованный шаблон очистки
- •13.8Отложенная инициализация объектов
- •Полезные ссылки
Установка объектных ссылок в null
Если ранее приходилось создавать СОМ-объекты в Visual Basic 6.0, то должно быть известно, что по завершении их использования предпочтительнее устанавливать эти ссылки в Nothing. На внутреннем уровне счетчик ссылок на объект СОМ уменьшалось на единицу, и когда он становился равным нулю, объект можно было удалять из памяти. Аналогичным образом программисты на C/C++ часто предпочитают устанавливать для переменных указателей значение null, гарантируя, что они больше не будут ссылаться на неуправляемую память.
Из-за упомянутых фактов, вполне естественно, может возникнуть вопрос о том, что же происходит в C# после установки объектных ссылок в null. Для примера изменим метод MyUser() следующим образом:
public static void MyUser()
{
UserInfo ui = new UserInfo();
ui = null;
}
Когда объектные ссылки устанавливаются в null, компилятор C# генерирует CIL-код, который заботится о том, чтобы ссылка больше не ссылалась ни на какой объект. Если теперь снова воспользоваться утилитой ildasm.ехе и заглянуть с ее помощью в CIL-код измененного метода MyUser(), можно обнаружить в нем код операции ldnull (который заталкивает значение null в виртуальный стек выполнения) со следующим за ним кодом операции stloc.O (который присваивает переменной ссылку null):
|
Однако обязательно следует понять, что установка ссылки в null никоим образом не вынуждает сборщик мусора немедленно приступить к делу и удалить объект из кучи, а просто позволяет явно разорвать связь между ссылкой и объектом, на который она ранее указывала. Благодаря этому, присваивание ссылкам значения null в C# имеет гораздо меньше последствий, чем в других языках на базе С (или VB 6.0), и совершенно точно не будет причинять никакого вреда.
13.2Роль корневых элементов приложения
Давайте рассмотрим вопрос о том, каким образом сборщик мусора определяет момент, когда объект уже более не нужен. Чтобы разобраться в стоящих за этим деталях, необходимо знать, что собой представляют корневые элементы приложения (application roots). Попросту говоря, корневым элементом (root) называется ячейка в памяти, в которой содержится ссылка на размещающийся в куче объект. Строго говоря, корневыми могут называться элементы любой из перечисленных ниже категорий:
Ссылки на глобальные объекты (хотя в C# они не разрешены, CIL-код позволяет размещать глобальные объекты).
Ссылки на любые статические объекты или статические поля.
Ссылки на локальные объекты в пределах кодовой базы приложения.
Ссылки на передаваемые методу параметры объектов.
Ссылки на объекты, ожидающие финализации
Любые регистры центрального процессора, которые ссылаются на объект.
Во время процесса сборки мусора исполняющая среда будет исследовать объекты в управляемой куче, чтобы определить, являются ли они по-прежнему достижимыми (т.е. корневыми) для приложения. Для этого среда CLR будет создавать графы объектов, представляющие все достижимые для приложения объекты в куче.
Главное усвоить то, что графы применяются для документирования всех достижимых объектов. Кроме того, следует иметь в виду, что сборщик мусора никогда не будет создавать граф для одного и того же объекта дважды, избегая необходимости выполнения подсчета циклических ссылок, который характерен для программирования в среде СОМ.
Чтобы увидеть все это на примере, предположим, что в управляемой куче содержится набор объектов с именами А, В, С, D, Е, F и G. Во время сборки мусора эти объекты (а также любые внутренние объектные ссылки, которые они могут содержать) будут исследованы на предмет наличия у них активных корневых элементов. После построения графа все недостижимые объекты (которыми в примере пусть будут объекты С и F) помечаются как являющиеся мусором. На рисунке показано, как примерно выглядит граф объектов в только что описанном сценарии (линии со стрелками следует воспринимать как "зависит от" или "требует"; например, "Е зависит от G и В", "А не зависит ни от чего" и т.д.).
|
После того как объект помечен для уничтожения (в данном случае это объекты С и F, поскольку в графе объектов они во внимание не принимаются), они будут удалены из памяти. Оставшееся пространство в куче будет после этого сжиматься до компактного состояния, что, в свою очередь, вынудит CLR изменить набор активных корневых элементов приложения (и лежащих в их основе указателей) так, чтобы они ссылались на правильное место в памяти (это делается автоматически и прозрачно). И, наконец, указатель на следующий объект тоже будет подстраиваться так, чтобы указывать на следующий доступный участок памяти. На следующем рисунке показано, как выглядит конечный результат этих изменений в рассматриваемом сценарии:
|
Собственно говоря, сборщик мусора использует две отдельных кучи, одна из которых предназначена специально для хранения очень больших объектов. Доступ к этой куче во время сборки мусора получается реже из-за возможных последствий в плане производительности, в которые может выливаться изменение места размещения больших объектов. Невзирая на этот факт, управляемая куча все равно может спокойно считаться единой областью памяти.
