- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Программирование на Visual C++. Архив рассылки - Алекс Jenter
Шрифт:
Интервал:
Закладка:
Чтобы определить новые пользовательские атрибуты, следует создать новый класс, унаследовав его от System.Attribute, и реализовать в этом классе public-конструктор:
using System;
[ AttributeUsage(AttributeTargets.All) ]
public class ColorAttribute : Attribute {
public String color;
public ColorAttribute(string c) { color = c;}
}
Атрибут AttributeUsage говорит, к чему будет применим новый атрибут – к классу, методу, свойству и т.п. Если класс атрибута заканчивается на Attribute, то атрибут можно будет использовать с или без этого суффикса. Например, следующие два примера идентичны, хотя последний и реже используется:
[ Color("Red") ]
class MyClass {}
[ ColorAttribute("Red") ]
class MyClass {}
Пользовательские атрибуты доступны в runtime через reflection-механизм. Код, приведенный выше, определяет, какой цвет присвоен данному классу и присвоен ли он вообще:
using System;
String GetColor(Object o) {
Type t = o.GetType();
// Получаем тип объекта
// Получаем тип необходимого атрибута
Type at = typeof(ColorAttribute);
// Получаем все атрибуты этого типа
Attribute[] rga = t.GetCustomAttributes(at);
// Выходим, если атрибуты не заданы
if (rga.Length == 0) return null;
// Иначе извлекаем первый атрибут
ColorAttribute color = (ColorAttribute)rga[0];
return color.color;
}
Атрибуты – это мощный и универсальный механизм расширения метаинформации.
Динамический вызов на халяву. Поскольку информация о типах стандартна и доступна всегда для любого элемента сборки, runtime-сервисы могут динамически вызывать любой метод любого объекта. Это значит, что все объекты CLR могут быть использованы в скриптовых языках программирования. Также можно создавать сервисные визуальные компоненты, непосредственно взаимодействующие с любыми компонентами, и при этом совершенно не нужно иметь их исходных текстов.
Физическое размещение непрозрачно. clr основывается на совершенной информации о типах. Это значит, что ни один тип не остается неописанным, вплоть до типов и имен членов данных типа. Как ни странно, физическая раскладка памяти для данного типа и его экземпляров полностью скрыты. Смещения, размеры и выравнивание членов данных неизвестны. Если нужно экспортировать CLR-объект за пределы среды исполнения, CLR создает COM-Callable Wrapper (CCW), который работает переходником между классической конвенцией вызовов COM, основанной на IUnknown и stdcall во внутреннем формате вызовов CLR-среды.
Очень жалко, что у господ новаторов из Microsoft не хватило смелости попросту расширить стандарт COM и обеспечить поддержку этих улучшений в VS.Net. Так что всем, кто использует COM в своей работе и хочет шагать в ногу со временем, придется изучить еще и CLR. Хотя для разработчиков, чей разум не замутнен тонкостями COM, интеграция CLR и COM будет выглядеть довольно прозрачно. Чтобы использовать COM-объект в своих .Net-приложениях, необходимо будет только зарегистрировать этот объект, примерно так, как это делалось в VB 6. Для низкоуровневых программистов это значит, что для динамической генерации новых типов и перехвата доступа к уже существующим экземплярам нужна новая техника. System.Reflection.Emit дает возможность генерации новых типов; System.Runtime.Remoting дает возможность перехвата вызовов к существующим типам.
Иерархия типов с одним корнем! Почти во всех традиционных языках программирования есть и иерархия , таких, например как int, char и т.п. В COM имеется корневой тип для объектных ссылок – IUnknown. Все остальные типы отражаются в универсальном типе данных – VARIANT. И хотя в принципе VARIANT и может хранить объектные ссылки, но назвать его корнем для иерархии типов язык не поворачивается. Это подтверждается тем, что в VB 6 универсальный параметр можно было описать или как Object (то есть IDispatch), или как Variant. Да и у варианта были некоторые проблемы с информацией о типах при хранении некоторых типов данных. Например, при помещении в вариант значения Enum значение превращалось в целое число, и не было никаких возможностей узнать, к какому типу данных принадлежит значение.
В системе типов CLR нет ни IUnknown, ни VARIANT, ни (по сути) простых типов данных. Вместо этого все типы происходят от System.Object. Да, это значит, что простые типы, такие, как int или double, происходят от System.Object и являются настоящими объектами. Причем это справедливо для всех без исключения языков, поддерживающих .Net. В VB.Net и C# это становится частью языка, а в C++ осуществляется через специальное расширение – (C++ – единственный язык, который не был полностью уничтожен перед реинкарнацией. С его помощью можно будет создавать приложения сразу в бинарном виде и без CLR. По сути, родился новый язык. В новостных группах его уже окрестили MC++.). Функциональность поля vt структуры VARTYPE поглощена методом System.Object.GetType. И теперь она доступна из любого языка. Так, код на C++:
void Process(VARIANT value) {
switch (value.vt) {
case VT_I2:
ProcessAsShort(value.iVal);
break;
case VT_R8:
ProcessAsDouble(value.dblVal);
break;
case VT_BSTR:
ProcessAsString(value.bstrVal);
break;
case VT_UNKNOWN:
case VT_DISPATCH:
{
CComQIPtr<IFoo> spFoo(value.punkVal);
if (spFoo) ProcessAsFoo(spFoo);
else {
CComQIPtr<IBar> spBar(value.punkVal);
if (spBar) ProcessAsBar(spBar);
}
break;
}
}
}
можно заменить на следующий код на C#:
void Process(System.Object value) {
if (value is short) ProcessAsShort((short)value);
else if (value is double) ProcessAsDouble((double)value);
else if(value is System.String) ProcessAsString((System.String)value);
else if(value is IFoo) ProcessAsFoo((IFoo)value);
else if(value is IBar) ProcessAsBar((IBar)value);
}
Заметьте, что C#-код использует специальные операторы для проверки соответствия типов, и что оператор приведения типов выполняет приведение как для объектных ссылок, так и для простых типов.
Еще раз повторюсь, что код, подобный приведенному во втором листинге, можно написать на любом CLR-совместимом языке.
Классы с публичными членами. В com классы были именованными реализациями одного или более интерфейсов. И точка. Классам не позволялось иметь методы или свойства, не принадлежащие какому– либо интерфейсу. В CLR у классов могут быть public-члены. Это позволяет использовать методы как для реализации интерфейсов компонентов, так и в качестве одиноких методов в классах конечных приложений.
Множественное наследование. В clr есть две новации. Одна – реализация множественного наследования для интерфейсов. По всей видимости, это расширение сделано с целью избавиться от QueryInterface. QueryInterface должен быть заменен на операцию приведения типов. С точки зрения идеологии красивое решение, но не приведет ли оно к проблемам интеграции с COM? Вторая новация связана с запретом множественного наследования. Множественное наследование наряду с шаблонами и переопределением операторов были C++. Похоже, времена меняются. Множественное наследование не запрещено в чистом C++. Но его использование ограничено в MC++. VB.Net и C# вообще не поддерживают множественного наследования, но об этом мы еще поговорим при рассмотрении этих языков.
Делегаты. Делегирование – это по сути домысленная и доведенная до совершенства технология обратных (callback) вызовов. В COM все вызовы методов делались по объектным ссылкам, принадлежащим некому типу интерфейса. Чтобы создать обратную связь с объектом, обычно описывался новый событийный интерфейс, и создавалась его реализация. При этом если нужно было создать связь всего лишь по одному методу, все равно приходилось реализовывать весь интерфейс.
CLR-делегаты используются для привязки вызова метода объекта к переменной. Это гибрид указателей на функции в С или, точнее, на функции-члены в C++. Функционально делегаты похожи на интерфейсы с единственным методом, с тем отличием, что целевому типу нужно только иметь метод, чья сигнатура соответствует сигнатуре делегата.
Посмотрите на следующий пример:
public delegate void Hook();
public class MyClassEx {
Hook hook;
public void RegisterHook(Hook h) {
hook = h;
}
public void f() {
if (hook != null) hook(); // callback-вызов
}
}
Заметьте, что вместо интерфейса определяется простой тип-делегат. Заметьте ещё, что вызов перехватчика использует синтаксис, похожий на указатели функций С/C++. Разные языки VS.Net имеют различный синтаксис работы с делегатами, но внутренний механизм един.
Чтобы написать перехватчик MyClassEx, нужно просто реализовать метод, чья сигнатура соответствует сигнатуре делегата Hook:
public class MyHookEx {
public void AnyNameIWant() {