![](/user_photo/2706_HbeT2.jpg)
- •Сборки (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. Создание и использование итераторов.
- •Общие сведения о итераторах
Этап 2: определение члена-события
В C# член-событие объявляется ключевым словомevent. Каждому члену-событию определяется:
область действия
тип делегата, указывающий на прототип вызываемого метода (методов)
имя
Вот как выглядит член-событие нашего класса NewMail:
internal class MailManager
{
// Этап 2: определение члена-события
public event EventHandler<NewMailEventArgs> NewMail;
}
NewMail— имя события.
EventHandler<NewMailEventArgs> — тип члена-события.
Получатели уведомления о событии должны предоставлять метод обратного вызова, прототип которого совпадает с типом-делегатом EventHandler<NewMailEventArgs>.
Поскольку обобщенный делегат System.EventHandlerопределен так:
public delegate void EventHandler<TEventArgs>
(Object sender, TEventArgs e) where TEventArgs : EventArgs;
метод должен выглядеть так:
void MethodName(Object sender, NewMailEventArgs e);
Примечание:Многих удивляет, почему механизм событий требует, чтобы параметр sender был типа Object. Вообще-то, поскольку MailManager — единственный тип, реализующий события с объектом NewMailEventArgs, было бы разумнее использовать следующий прототип метода обратного вызова:
void MethodName(MailManager sender, NewMailEventArgs e);
Причина необходимости того, чтобы параметр sender был типа Object, — в наследовании. Что произойдет, если MailManager задействовать в качестве базового класса для создания класса SmtpMailManager? В методе обратного вызова придется в прототипе задать параметр sender как SmtpMailManager, а не MailManager, но этого делать нельзя, так как SmtpMailManager просто унаследовал событие NewMail. Поэтому код, ожидающий от SmtpMailManager информацию о событии, все равно будет вынужден приводить аргумент sender к типу SmtpMailManager. Иначе говоря, приведение все равно необходимо, поэтому проще всего сделать так, чтобы sender был типа Object.
Еще одна причина того, что sender относят к типу Object — простая гибкость. Это позволяет использовать делегат нескольким типам, которые поддерживают событие, передающее объект NewMailEventArgs. В частности, класс PopMailManager мог бы использовать делегат, даже если бы не наследовал классу MailManager.
Механизм событий требует, чтобы в имени делегата и методе обратного вызова производный от EventArgs параметр назывался е. Единственная причина — обеспечить дополнительное однообразие, облегчая и упрощая для разработчиков изучение и реализацию событий.
Механизм событий требует, чтобы все обработчики возвращали void. Это обязательно, потому что при возникновении события могут вызываться несколько методов обратного вызова и невозможно получить у них всех возвращаемое значение. Тип void просто запрещает методам возвращать какое бы то ни было значение. К сожалению, в библиотеке FCL есть обработчики событий, в частности ResolveEventHandler, в которых Microsoft не следует собственным правилам и возвращает объект типа Assembly.
Этап 3: определение метода, ответственного за уведомление зарегистрированных объектов о событии
В соответствии с соглашением, в классе должен быть виртуальный защищенный метод, вызываемый из кода класса и его потомков при возникновении события. Этот метод принимает один параметр, объект MailMsgEventArgs, содержащий дополнительные сведения о событии.
Реализация по умолчанию этого метода проверяет, есть ли объекты, зарегистрировавшиеся для получения уведомления о событии, и при положительном результате проверки уведомляет зарегистрированные методы о возникновении события. Вот как выглядит этот метод в нашем классе MailManager.
internal class MailManager
{
// Если этот класс изолированный, нужно сделать метод закрытым или невиртуальным.
protected virtual void OnNewMail(NewMailEventArgs e)
{
// Сохранить поле делегата во временном поле
// для обеспечения безопасности потоков.
EventHandler<NewMailEventArgs> temp = NewMail;
// Если есть объекты, зарегистрированные для получения
// уведомления о событии, уведомляем их.
if (temp != null)
temp(this, e);
}
}
Обратите внимание, что метод OnNewMail определяет временную локальную переменную temp, которая инициализируется самим членом-событием. Далее temp сравнивается с null и в случае неравенства используется для инициирования события. Эта временная переменная необходима для предотвращения возможных проблем с синхронизацией потоков.
Если вместо использования temp просто сослаться на NewMail, вполне возможно, что поток «увидит», что NewMail не равно null. Но позднее, непосредственно перед генерацией события, другой поток может переопределить NewMail, присвоив null. В такой ситуации при попытке инициировать событие CLR вернет исключение NullReferenceException. Временная переменная temp решает проблему и избавляет от возможности генерации исключения NullReferenceException.
Тип, производный от MailManager, может свободно переопределять метод OnNewMail, что позволяет производному типу контролировать срабатывание события. Таким образом, производный тип может обрабатывать новые сообщения любым способом по собственному усмотрению.
Обычно производный тип вызывает метод OnNewMail базового типа, в результате зарегистрированный объект получает уведомление. Однако производный тип может и отказаться от пересылки уведомления о событии.