- •Сборки (assembly) в среде .Net. Проблема версионности сборок и ее решение.
- •Номер версии в .Net
- •Сведения о версии
- •Номер версии сборки
- •Информационная версия сборки
- •Общая система типов данных в среде .Net. Размерные и ссылочные типы данных. Типы, переменные и значения
- •Пользовательские типы
- •Система общих типов cts
- •Ссылочные типы
- •Типы литеральных значений
- •Неявные типы, анонимные типы и типы, допускающие значение null
- •Упаковка и распаковка размерных типов данных в среде .Net.
- •Производительность
- •Упаковка–преобразование
- •Распаковка-преобразование
- •Ссылочные типы данных. Объектная модель в среде .Net и языке c#.
- •Модели ручной и автоматической утилизации динамической памяти, их сравнительная характеристика. Модель с ручным освобождением памяти
- •Модель с автоматической «сборкой мусора»
- •Модель автоматической утилизации динамической памяти, основанная на сборке мусора. Проблема недетерминизма.
- •Модель автоматической утилизации динамической памяти, основанная на аппаратной поддержке (тегированной памяти).
- •Сборка мусора в среде .Net. Построение графа достижимых объектов.
- •Сборка мусора в среде .Net. Механизм поколений объектов.
- •Модель детерминированного освобождения ресурсов в среде .Net. Интерфейс iDisposable и его совместное использование с завершителем (методом Finalize).
- •«Мягкие ссылки» и кэширование данных в среде .Net.
- •Краткие и длинные слабые ссылки
- •Краткая ссылка
- •Длинная ссылка
- •Правила использования слабых ссылок
- •Динамические массивы в среде .Net и языке c#.
- •Приведение типов в массивах
- •Все массивы неявно реализуют /Enumerable, /Collection и iList
- •Передача и возврат массивов
- •Создание массивов с ненулевой нижней границей
- •Производительность доступа к массиву
- •Небезопасный доступ к массивам и массивы фиксированного размера
- •Делегаты в среде .Net и механизм их работы. Знакомство с делегатами
- •Использование делегатов для обратного вызова статических методов
- •Использование делегатов для обратного вызова экземплярных методов
- •Правда о делегатах
- •Использование делегатов для обратного вызова множественных методов (цепочки делегатов)
- •Поддержка цепочек делегатов в с#
- •Расширенное управление цепочкой делегатов
- •Упрощение синтаксиса работы с делегатами в с#
- •Упрощенный синтаксис № 1: не нужно создавать объект-делегат
- •Упрощенный синтаксис № 2: не нужно определять метод обратного вызова
- •Упрощенный синтаксис № 3: не нужно определять параметры метода обратного вызова
- •Упрощенный синтаксис № 4: не нужно вручную создавать обертку локальных переменных класса для передачи их в метод обратного вызова
- •Делегаты и отражение
- •События в среде .Net; реализация событий посредством делегатов. События
- •Этап 1: определение типа, который будет хранить всю дополнительную информацию, передаваемую получателям уведомления о событии
- •Этап 2: определение члена-события
- •Этап 3: определение метода, ответственного за уведомление зарегистрированных объектов о событии
- •Этап 4: определение метода, транслирующего входную информацию в желаемое событие
- •Как реализуются события
- •Создание типа, отслеживающего событие
- •События и безопасность потоков
- •Явное управление регистрацией событий
- •Конструирование типа с множеством событий
- •Исключительные ситуации и реакция на них в среде .Net. Достоинства
- •Механика обработки исключений
- •Блок try
- •Блок catch
- •Блок finally
- •Генерация исключений
- •Определение собственных классов исключений
- •Исключения в платформе .Net Framework
- •Исключения и традиционные методы обработки ошибок
- •Управление исключениями средой выполнения
- •Фильтрация исключений среды выполнения
- •21 Средства многопоточного программирования в среде .Net. Автономные потоки. Пул потоков.
- •Создание и использование потоков
- •Запуск и остановка потоков
- •Методы управления потоками
- •Безопасные точки
- •Свойства потока
- •Потоки Windows в clr
- •К вопросу об эффективном использовании потоков
- •Пул потоков в clr
- •Ограничение числа потоков в пуле
- •22. Асинхронные операции в среде .Net. Асинхронный вызов делегатов.
- •23. Синхронизация программных потоков в среде .Net. Блокировки.
- •Двойная блокировка
- •Класс ReaderWriterLock
- •Использование объектов ядра Windows в управляемом коде
- •Вызов метода при освобождении одного объекта ядра
- •24. Синхронизация программных потоков в среде .Net. Атомарные (Interlocked-операции). Семейство lnterlocked-методов
- •25. Прерывание программных потоков в среде .Net. Особенности исключительной ситуации класса ThreadAbortException.
- •26. Мониторы в среде .Net. Ожидание выполнения условий с помощью методов Wait и Pulse. Класс Monitor и блоки синхронизации
- •«Отличная» идея
- •Реализация «отличной» идеи
- •Использование класса Monitor для управления блоком синхронизации
- •Способ синхронизации, предлагаемый Microsoft
- •Упрощение кода c# при помощи оператора lock
- •Способ синхронизации статических членов, предлагаемый Microsoft
- •Почему же «отличная» идея оказалась такой неудачной
- •Целостность памяти, временный доступ к памяти и volatile-поля
- •Временная запись и чтение
- •Поддержка volatile-полей в с#
- •27. Асинхронный вызов делегатов.
- •Общие типы (Generics)
- •Инфраструктура обобщений
- •Открытые и закрытые типы
- •Обобщенные типы и наследование
- •Проблемы с идентификацией и тождеством обобщенных типов
- •«Распухание» кода
- •Обобщенные интерфейсы
- •Обобщенные делегаты
- •Обобщенные методы
- •Логический вывод обобщенных методов и типов
- •Обобщения и другие члены
- •Верификация и ограничения
- •Основные ограничения
- •Дополнительные ограничения
- •Ограничения конструктора
- •Другие вопросы верификации
- •Приведение переменной обобщенного типа
- •Присвоение переменной обобщенного типа значения по умолчанию
- •Сравнение переменной обобщенного типа с null
- •Сравнение двух переменных обобщенного типа
- •Использование переменных обобщенного типа в качестве операндов
- •Преимущества использования общих типов
- •29. Итераторы в среде .Net. Создание и использование итераторов.
- •Общие сведения о итераторах
Обобщенные делегаты
Поддержка обобщенных делегатов в CLR позволяет передавать методам обратного вызова любые типы объектов, обеспечивая при этом безопасность типов. Благодаря обобщенным делегатам экземпляры значимого типа могут передаваться методам обратного вызова без упаковки. Как уже говорилось в главе 15, делегат — это просто определение класса с помощью четырех методов: конструктора и методов Invoke, Beginlnvoke и Endlnvoke. При определении типа-делегата с параметрами-типами, компилятор определяет методы класса делегата, а параметры-типы применяются ко всем методам, параметры и возвращаемые значения которых относятся к указанному параметру-типу. Например, обобщенный делегат определяется следующим образом:
public delegate TReturn CallMe<TReturn, TKey, TValue>(TKey key, TValue value);
Компилятор превращает его в класс, который логически выглядит так:
public sealed class CallMe<TReturn, TKey, TValue> : MulticastDelegate
{
public CallMe(Object _object, IntPtr method);
public TReturn Invoke(TKey key, TValue value);
public IAsyncResult BeginInvoke(TKey key, TValue value,
AsyncCallback callback, Object _object);
public TReturn EndInvoke(IAsyncResult result);
}
В составе FCL есть много обобщенных типов-делегатов. Большинство из них используется при работе с наборами. Например:
// Обычно служит для выполнения действия над элементом набора.
public delegate void Action<T>(T obj);
// Обычно используется при сравнении элементов двух наборов в целях сортировки.
public delegate Int32 Comparison<T>(T x, T y);
// Обычно служит для преобразования типа элемента набора.
public delegate TOutput Converter<TInput, TOutput>(TInput input);
// Обычно применяется, чтобы узнать, прошел ли элемент набора тест.
public delegate Boolean Predicate<T>(T obj);
Следующий обобщенный делегат, поставляемый с FCL, используется для событий:
public delegate void EventHandler<TEventArgs>(
object sender, TEventArgs e) where TEventArgs : EventArgs;
Оператор where в этом примере называют ограничением.
Обобщенные методы
При определении обобщенного ссылочного и значимого типа или интерфейса все методы, определенные в этих типах, могут ссылаться на любой параметр-тип, заданный этим типом. Параметр-тип может использоваться как параметр метода, возвращаемое значение метода или как заданная внутри него локальная переменная. Но CLR также позволяет методу задавать собственные параметры-типы, которые могут использоваться в качестве параметров, возвращаемых значений или локальных переменных. Вот немного искусственный пример типа, определяющего параметр-тип, и метода с собственным параметром-типом:
internal sealed class GenericType<T>
{
private T m_value;
public GenericType(T value) { m_value = value; }
public TOutput Converter<TOutput>()
{
TOutput result = (TOutput)Convert.ChangeType(m_value, typeof(TOutput));
return result;
}
}
internal sealed class GenericType<T>
{
private T m_value;
public GenericType(T value)
{
m_value = value;
}
public TOutput Converter<TOutput>()
{
TOutput result = (TOutput)Convert.ChangeType(m_value, typeof(TOutput));
return result;
}
Здесь в классе GenericType определяется собственный параметр-тип (Т), а в методе Converter — собственный параметр-тип (TOutput). Благодаря этому можно создать класс GenericType, работающий с любым типом. Метод Converter преобразует объект, на который ссылается поле m_value, в другие типы в зависимости от аргумента-типа, переданного ему при его вызове. Наличие параметров-типов и параметров метода дает небывалую гибкость. Удачный пример обобщенного метода — метод Swap:
private static void Swap<T>(ref T o1, ref T o2)
{
T temp = o1;
o1 = o2;
o2 = temp;
}
//Теперь вызывать Swap из кода можно следующим образом:
private static void CallingSwap()
{
Int32 n1 = 1, n2 = 2;
Console.WriteLine("n1={0}, n2={1}", n1, n2);
Swap<Int32>(ref n1, ref n2);
Console.WriteLine("n1={0}, n2={1}", n1, n2);
String s1 = "Aidan", s2 = "Kristin";
Console.WriteLine("s1={0}, s2={1}", s1, s2);
Swap<String>(ref s1, ref s2);
Console.WriteLine("s1={0}, s2={1}", s1, s2);
}
Использование обобщенных типов с методами, принимающими параметры out и ref особенно интересно тем, что переменные, передаваемые в качестве аргумента out/ref, должны быть того же типа, что и параметр метода, чтобы избежать возможных нарушений безопасности типов. В сущности, именно поэтому методы Exchange и Compare-Exchange класса Interlocked поддерживают обобщенную перегрузку:
public static class Interlocked
{
public static T String<T>(ref T locationl, T value) where T : class;
public static T CompareExchange<T>(ref T locationl, T value, T comparand) where T : class;
}