- •Сборки (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 можно выполнить неявное приведение типа элементов исходного массива, если элементы относятся к ссылочному типу. Условия успешного приведения: оба типа массивов должны быть одной размерности, а также должно иметь место неявное или явное преобразование из типа элементов исходного массива в целевой тип. CLR не допускает приведение массивов с элементами значимых типов к другому типу. (Однако нужного результата позволяет достичь метод Аггау.Сору, создающий новый массив.) Вот пример приведения типа в массиве:
// Создаем двумерный массив FileStream.
FileStream[, ] fs2dim = new FileStream[5, 10];
// Неявное приведение к двумерному массиву типа Object.
Object[,] o2dim = fs2dim;
// Нельзя привести двумерный массив к одномерному.
// Ошибка компиляции CS0030: Невозможно привести 'object[*,*]' к
// 'System. 10.Stream[]'.
Stream[] sldim = (Stream[]) o2dim;
// Явное приведение к двумерному массиву Stream.
Stream[,] s2dim = (Stream[,]) o2dim;
// Явное приведение к двумерному массиву String.
// Компиляция проходит, но на этапе выполнения генерируется InvalidCastException. String[,] st2dim = (String[,]) o2dim;
// Создаем одномерный массив Int32 (значимый тип).
Int32[] ildim = new Int32[5];
// Нельзя привести к другому типу массив значимого типа.
// Ошибка компиляции CS0030: Невозможно привести 'int[]' к -object[]'.
0bject[] oldim = (0bject[]) ildim;
// Создаем новый массив, а затем применяем Array.Сору для приведения
// каждого элемента в целевом массиве к желаемому типу.
// Следующий код создает массив ссылок на упакованные элементы типа Int32.
0bject[] obldim = new 0bject[i1dim.Length];
Array.Copy(i1dim, obldim, ildim.Length);
Метод Array.Copy не только копирует элементы одного массива в другой. Действуя, как функция memmove языка С, он, в отличие от memmove правильно обрабатывает перекрывающиеся области памяти. Он также способен, если требуется, преобразовывать элементы массива при их копировании. Метод Сору может выполнять:
упаковку элементов значимого типа в элементы ссылочного типа, например при копировании Int32[] в ObjectfJ;
распаковку элементов ссылочного типа в элементы значимого типа, например при копировании Objectf] в Int32[];
расширение (widening) элементарных значимых CLR-типов, например при копировании Ш32[] в DoublefJ;
приведение элементов с потерями при копировании между массивами разного типа, для которых нельзя определить совместимость по типу массива, например при приведении ObjectfJ к IFormattable[]. Если все объекты Object[] реализует IFormattable[], приведение пройдет успешно.
Вот один из примеров применения Сору:
//Определяем значимый тип, в котором реализован интерфейс.
internal struct MyValueType : IComparable
{
public Int32 CompareTo(0bject obj)
{ }
}
public static class Program
{
public static void MainQ
{
// Создаем массив из 100 элементов значимого типа.
MyValueType[] src = new MyValueType[100];
// Создаем массив ссылок IComparable.
IComparable[] dest = new IComparable[src.Length];
// Инициализируем массив элементов IComparable ссылками
// на упакованные версии элементов в исходном массиве.
Array.Copy(src, dest, src.Length);
}
}
Нетрудно догадаться, что FCL достаточно часто использует достоинства метода Аггау.Сору.
В некоторых ситуациях удобно приводить массив из одного типа в другой, что называют ковариациеймассива (array covariance). Надо иметь в виду, что ковариация сильно снижает производительность. Допустим, вы написали такой код:
String[] sa = new String[100];
0bject[] oa = sa; //oa ссылается на массив элементов String.
оа[5] = "Jeff"; //Удар по производительности: CLR проверяет,
//является ли оа типом String; проверка проходит успешно.
оа[3] = 5; //Удар по производительности: CLR проверяет,
//является ли оа типом Int32;
//генерируется исключение ArrayTypeMismatchException.
Здесь тип переменной оа определен как Object[], однако в реальности она ссылается на StringfJ. Компилятор разрешит написать код, пытающийся разместить 5 в элементе массива, потому что 5 относится к типу Int32, производному от Object.
Естественно, CLR стоит на страже безопасности типов, поэтому при присвоении значения элементу массива проверяет корректность операции. Поэтому в процессе выполнения проверяет, содержит ли массив элементы Int32. В данном случае это не так, поэтому присвоение признается некорректным, и CLR генерирует исключение ArrayTypeMismatchException.
Примечание:Если просто нужно скопировать часть элементов из одного массива в другой, метод BlockCopy типа SystemBuffer выполнит это быстрее, чем Аггау.Сору. Однако BlockCopy поддерживает только элементарные типы и не предоставляет такие же широкие возможности по приведению типов, как Сору. Параметры типа Int32 выражаются в виде смещений байт, а не индексов элементов. BlockCopy разработан для копирования поразрядно совместимых данных из массива одного типа в другой массив битовых таблиц, например копирования Byte[], содержащего Unicode-символы (с соответствующим порядком байт), в CharfJ. Этот метод частично восполняет невозможность считать массивы просто блоком памяти любого типа.
Если нужно корректно скопировать подмножество элементов из одного массива в другой, следует использовать метод ConstrainedCopy типа SystemArray. Он гарантирует, что операция копирования завершится верно или будет сгенерировано исключение, уничтожающее все данные в целевом массиве. Это позволяет использовать ConstrainedCopy в области выполнения с ограничениями (constrained execution region, CER). Такое гарантированное поведение обусловлено тем, что ConstrainedCopy требует, чтобы тип элементов исходного массива совпадал или был производным от типа элементов целевого массива. Кроме того, метод не выполняет никакой упаковки, распаковки или приведения с потерями.
Все массивы неявно наследуют классу SystemArray
Если объявить переменную-массив следующим образом, CLR автоматически создаст тип FileStream[] для домена AppDomain.
FileStream[] fsArray;
Тип FileStream[] неявно наследует типу SystemArray, поэтому получает в наследство все экземплярные методы и свойства SystemArray. Их можно вызывать, используя переменную fsArray. Это сильно упрощает работу с массивами, потому что в SystemArray определена масса полезных методов и свойств, в том числе Clone, СоруТо, GetLength, GetLongLength, GetLowerBound, GetUpperBound, Length и Rank.
Тип SystemArray также предоставляет много исключительно полезных статических методов для работы с массивами, в том числе AsReadOnfy, BinarySearch, Clear, ConstrainedCopy, ConvertAll, Copy, Exists, Find, FindAll, Findlndex, FindLast, FindLastlndex, ForEach, IndexOf, LastlndexOf, Resize, Reverse, Sort и TrueForAll. В качестве параметра эти методы принимают ссылку на массив. У этих методов есть также много перегруженных версий. Вообще-то многие из этих методов предоставляют обобщенные перегруженные версии, обеспечивающие контроль типов во время компиляции и высокую производительность.