
- •Введение Обзор .Net. Основные понятия
- •Программа на c#
- •Основы языка Пространство имён
- •Система типов
- •Класс и Структура. Первое приближение
- •Литералы. Представление значений
- •Арифметические литералы
- •Логические литералы
- •Символьные литералы
- •Символьные escape-последовательности
- •Строковые литералы
- •Операции и выражения
- •Приоритет операций
- •Приведение типов
- •Особенности выполнения арифметических операций
- •Особенности арифметики с плавающей точкой
- •Константное выражение
- •Переменные элементарных типов. Объявление и инициализация
- •Константы
- •Перечисления
- •Объявление переменных. Область видимости и время жизни
- •Управляющие операторы
- •Синтаксис объявления метода
- •Вызов метода
- •Перегрузка методов
- •Способы передачи параметров при вызове метода
- •Передача параметров. Ссылка и ссылка на ссылку как параметры
- •Сравнение значений ссылок
- •This в нестатическом методе
- •Свойства
- •Обработка исключений
- •Массив. Объявление
- •Инициализация массивов
- •Примеры инициализации массивов
- •Два типа массивов: Value Type and Reference Type
- •Встроенный сервис по обслуживанию простых массивов
- •Реализация сортировки в массиве стандартными методами
- •Подробнее о массивах массивов (jagged array)
- •Массивы как параметры
- •Спецификатор params
- •Main в классе. Точка входа
- •Создание объекта. Конструктор
- •Операция new
- •В управляемой памяти нет ничего, что бы создавалось без конструктора
- •Кто строит конструктор умолчания
- •This в контексте конструктора
- •Перегрузка операций
- •Синтаксис объявления операторной функции
- •Унарные операции. Пример объявления и вызова
- •Бинарные операции
- •Определение операций конъюнкция и дизъюнкции
- •И вот результат…
- •Пример. Свойства и индексаторы
- •Explicit и implicit. Преобразования явные и неявные
- •Наследование
- •Наследование и проблемы доступа
- •Явное обращение к конструктору базового класса
- •Кто строит базовый элемент
- •Переопределение членов базового класса
- •Наследование и new модификатор
- •Полное квалифицированное имя. Примеры использования
- •Прекращение наследования. Sealed спецификатор
- •Абстрактные функции и абстрактные классы
- •Ссылка на объект базового класса
- •Операции is и as
- •Виртуальные функции. Принцип полиморфизма
- •Интерфейсы
- •Делегаты
- •События
- •События и делегаты. Различия
- •Атрибуты, сборки, рефлексия Рефлексия (отражение) типов
- •Реализация отражения. Type, InvokeMember, BindingFlags
- •Атрибуты
- •Сборка. Класс Assembly
- •Класс сборки в действии
- •Разбор полётов
- •Класс System.Activator
- •Версия сборки
- •Файл конфигурации приложения
- •Общедоступная сборка
- •Игры со сборками из gac
- •Динамические сборки
- •Динамическая сборка: создание, сохранение, загрузка, выполнение
- •Ввод-вывод Базовые операции
- •Потоки: байтовые, символьные, двоичные
- •Предопределённые потоки ввода-вывода
- •Функция ToString()
- •Консольный ввод-вывод. Функции-члены класса Console
- •Консольный вывод. Форматирование
- •Функции вывода. Нестандартное (custom) форматирование значений.
- •Консольный ввод. Преобразование значений
- •Файловый ввод-вывод
- •Потоки Процесс, поток, домен
- •Домен приложения
- •Обзор пространства имён System.Threading
- •Многопоточность
- •Виды многопоточности
- •А кто в домене живёт…
- •Класс Thread. Общая характеристика
- •Именование потока
- •Игры с потоками
- •Характеристики точки входа дополнительного потока
- •Запуск вторичных потоков
- •Приостановка выполнения потока
- •Отстранение потока от выполнения
- •Завершение потоков
- •Метод Join()
- •Состояния потока (перечисление ThreadState)
- •Одновременное пребывание потока в различных состояниях
- •Фоновый поток
- •Приоритет потока
- •Передача данных во вторичный поток
- •Извлечение значений (данных) с помощью Callback методов
- •Организация взаимодействия потоков
- •1. Посредством общедоступных (public) данных
- •2. Посредством общедоступных (public) свойств
- •3. Посредством общедоступных очередей
- •Состязание потоков
- •Блокировки и тупики
- •Очереди. Основа интерфейса взаимодействия
- •Безопасность данных и критические секции кода
- •Пример организации многопоточного приложения
- •Очередь как объект синхронизации
- •Синхронизация работы потоков при работе с общими ресурсами
- •1. Организация критических секций
- •2. Специальные возможности мониторов
- •Рекомендации по недопущению блокировок потоков
- •Форма Класс Form
- •Форма: управление и события жизненного цикла
- •Форма: контейнер как элемент управления
- •Разница между элементами управления и компонентами.
- •Свойства элементов управления. Anchor и Dock
- •Extender providers. Провайдеры дополнительных свойств
- •Validating и Validated элементов управления
- •Управление посредством сообщений
- •Стандартный делегат
- •Делегат EventHandler
- •Класс Application
- •События класса Application
- •Примеры перехвата сообщений
- •Метод WndProc
- •Пример переопределения WndProc
- •Контекст приложения
- •Применение классов GraphicsPath и Region. Круглая форма
- •Собственные элементы управления
- •Литература
Атрибуты
Атрибут – средство добавления ДЕКЛАРАТИВНОЙ информации к элементам программного кода. Назначение атрибутов – внесение всевозможных не предусмотренных обычным ходом выполнения приложения изменений:
описание взаимодействия между модулями,
дополнительная информация, используемая при работе с данными (управление сериализацией),
отладка,
много чего другого.
Эта декларативная информация составляет часть метаданных кода. Она может быть использована при помощи механизмов отражения.
Структура атрибута регламентирована. Атрибут – это класс. Общий предок всех атрибутов – класс System.Attribute.
Информация, закодированная с использованием атрибутов, становится доступной в процессе ОТРАЖЕНИЯ (рефлексии типов).
Атрибуты типизированы.
.NET способна прочитать информацию в атрибутах и использовать её в соответствии с предопределёнными правилами или замыслами разработчика. Различаются
Предопределённые атрибуты. В .NET реализовано множество атрибутов с предопределёнными значениями:
DllImport – для загрузки .dll файлов.
Serializable – означает возможность сериализации свойств объекта-представителя класса.
NonSerialized – обозначает данные-члены класса как несериализуемые. Карандаши не сереализуются.
Производные (пользовательские) атрибуты могут определяться и использоваться в соответствии с замыслами разработчика. Возможно создание собственных (пользовательских) атрибутов. Главные условия:
соблюдение синтаксиса,
соблюдение принципа наследования.
В основе пользовательских атрибутов – всё та же система типов с наследованием от базового класса System.Attribute.
И не спроста! В конце-концов, информация, содержащаяся в атрибутах, предназначается для Framework.NET и она должна суметь в ней разбираться. Пользователи или другие инструментальные средства должны уметь кодировать и декодировать эту информацию.
Добавлять атрибуты можно к:
сборкам,
классам,
элементам класса,
структурам,
элементам структур,
параметрам,
возвращаемым значениям.
Следующий пример является демонстрацией объявление и применения производных атрибутов.
using System;
using System.Reflection;
namespace CustomAttrCS
{
// Перечисление of animals.
// Start at 1 (0 = uninitialized).
public enum Animal
{
// Pets.
Dog = 1,
Cat,
Bool,
}
// Перечисление of animals.
// Start at 1 (0 = uninitialized).
public enum Color
{
// Colors.
Red = 1,
Brown,
White,
}
// Класс пользовательских атрибутов.
public class AnimalTypeAttribute : Attribute
{//======================================================================
// Данное-член типа перечисление.
protected Animal thePet;
protected string WhoIs(Animal keyPet)
{
string retStr = “”;
switch (keyPet)
{
case Animal.Dog: retStr = “This is the Dog!”; break;
case Animal.Cat: retStr = “This is the Cat!”; break;
case Animal.Bool: retStr = “This is the Bool!”; break;
default: retStr = “Unknown animal!”; break;
}
return retStr;
}
// Конструктор вызывается при установке атрибута.
public AnimalTypeAttribute(Animal pet)
{
thePet = pet;
Console.WriteLine(«{0}», WhoIs(pet));
}
// Свойство, демонстрирующее значение атрибута.
public Animal Pet
{
get
{
return thePet;
}
set
{
thePet = Pet;
}
}
}//======================================================================
// Ещё один класс пользовательских атрибутов.
public class ColorTypeAttribute : Attribute
{//======================================================================
// Данное-член типа перечисление.
protected Color theColor;
// Конструктор вызывается при установке атрибута.
public ColorTypeAttribute(Color keyColor)
{
theColor = keyColor;
}
// Свойство, демонстрирующее значение атрибута.
public Color ColorIs
{
get
{
return theColor;
}
set
{
theColor = ColorIs;
}
}
}//======================================================================
// A test class where each method has its own pet.
class AnimalTypeTestClass
{//======================================================================
// Содержит объявления трёх методов, каждый из которых
// предваряется соответствующим ПОЛЬЗОВАТЕЛЬСКИМ атрибутом.
// У метода может быть не более одного атрибута данного типа.
[AnimalType(Animal.Dog)]
[ColorType(Color.Brown)]
public void DogMethod()
{
Console.WriteLine(“This is DogMethod()...”);
}
[AnimalType(Animal.Cat)]
public void CatMethod()
{
Console.WriteLine(“This is CatMethod()...”);
}
[AnimalType(Animal.Bool)]
[ColorType(Color.Red)]
public void BoolMethod(int n, string voice)
{
int i;
Console.WriteLine(“This is BoolMethod!”);
if (n > 0) for (i = 0; i < n; i++)
{
Console.WriteLine(voice);
}
}
}//======================================================================
class DemoClass
{//======================================================================
static void Main(string[] args)
{
int invokeFlag;
int i;
// И вот ради чего вся эта накрутка производилась...
// Объект класса AnimalTypeTestClass под именем testClass
// представляет собой КОЛЛЕКЦИЮ методов, каждый из которых
// снабжён соответствующим ранее определённым пользовательским
// СТАНДАРТНЫМ атрибутом. У класса атрибута AnimalTypeAttribute есть всё,
// что положено иметь классу, включая конструктор.
AnimalTypeTestClass testClass = new AnimalTypeTestClass();
// Так вот создали соответствующий объект-представитель класса...
// Объект-представитель класса сам может служить источником информации
// о собственном классе. Информация о классе представляется методом GetType()
// в виде объекта - представителя класса Type. Информационная капсула!
Type type = testClass.GetType();
// Из этой капсулы можно извлечь множество всякой «полезной» информации...
// Например, можно получить коллекцию (массив) элементов типа MethodInfo
// (описателей методов), содержащую список описателей методов, объявленных
// в данном классе. В список будет включена информация о ВСЕХ методах класса.
// О тех, которые были определены явным образом и те, которые были унаследованы
// от базовых классов. И по этому списку описателей методов мы пройдём
// победным маршем («Ha-Ha-Ha») оператором foreach.
i = 0;
foreach(MethodInfo mInfo
in
type.GetMethods())
{
invokeFlag = 0;
Console.WriteLine(“#####{0}#####{1}#####”, i, mInfo.Name);
// И у каждого из методов мы спросим относительно множества атрибутов,
// которыми метод был снабжён при объявлении класса.
foreach (Attribute attr
in
Attribute.GetCustomAttributes(mInfo))
{
Console.WriteLine(“~~~~~~~~~~”);
// Check for the AnimalType attribute.
if (attr.GetType() == typeof(AnimalTypeAttribute))
{
Console.WriteLine(“Method {0} has a pet {1} attribute.”,
mInfo.Name,
((AnimalTypeAttribute)attr).Pet);
// Посмотрели значение атрибута - и если это Animal.Bool - подняли флажок.
if (((AnimalTypeAttribute)attr).Pet.CompareTo(Animal.Bool) == 0) invokeFlag++;
}
if (attr.GetType() == typeof(ColorTypeAttribute))
{
Console.WriteLine(“Method {0} has a color {1} attribute.”,
mInfo.Name,
((ColorTypeAttribute)attr).ColorIs);
// Посмотрели значение атрибута - и если это Animal.Bool - подняли флажок.
if (((ColorTypeAttribute)attr).ColorIs.CompareTo(Color.Red) == 0) invokeFlag++;
}
// И если случилось счастливое совпадение значений атрибутов метода,
// метод выполняется.
// Метод Invoke в варианте с двумя параметрами:
// объект-представитель исследуемого класса
// (в данном случае AnimalTypeTestClass), и массив объектов - параметров.
if (invokeFlag == 2)
{
object[] param = {5,”Mmmuuu-uu-uu!!! Mmm...”};
mInfo.Invoke(new AnimalTypeTestClass(),param);
}
Console.WriteLine(“~~~~~~~~~~”);
}
Console.WriteLine(“#####{0}#####”, i);
i++;
}
}
}//======================================================================
}