- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание - Эндрю Троелсен
Шрифт:
Интервал:
Закладка:
В следующем фрагменте программного кода обратите внимание на то, что строка, содержащая тип и имя каждого из параметров, строится с помощью вложенного цикла foreach.
public static void ListMethods(Type t) {
Console.WriteLine(***** Методы *****");
MethodInfo[] mi = t.GetMethods();
foreach (MethodInfo m in mi) {
// Получение возвращаемого значения.
string retVal = m.ReturnType.FullName;
string paramInfo = "(";
// Получение параметров.
foreach (ParameterInfo pi in m.GetParameters()) {
paramInfo += string.Format("{0} {1}", pi.ParameterType, pi.Name);
}
paramInfo += ")";
// Отображение основных характеристик метода.
Console.WriteLine("-›{0} {1} (2}", retVal, m.Name, paramInfo);
}
Console.WriteLine(");
}
Если выполнить это обновленное приложение теперь, методы соответствующего типа будут описаны более подробно. Для примера на рис. 12.3 показаны метаданные методов для типа System.Globalization.GregorianCalendar.
Рис. 12.3. Подробное описание методов System.Globalization.GregorianCalendar
Весьма увлекательно, не так ли? Ясно, что пространство имен System.Reflection и класс System.Type позволяют отображать многие другие характеристики типа, а не только те, которые в настоящий момент реализованы в MyTypeViewer. Вы вправе надеяться на то, что можно будет исследовать события типа, выяснить, какие интерфейсы реализованы явно, получить список обобщенных параметров для заданных членов и проверить множество других характеристик.
Но и в нынешнем своем виде ваш обозреватель объектов уже кое-что умеет. Главным его ограничением, конечно же, является то, что у вас нет никакой возможности отображать объекты, размещенные вне данного компоновочного блока (MyTypeViewer) или всегда доступного mscorlib.dll. В связи с этим остается открытым вопрос: "Как строить приложения, которые могут загружать (и отображать) компоновочные блоки, о которых нет информации во время компиляции?"
Исходный код. Проект MyTypeViewer размещен в подкаталоге, соответствующем главе 15.
Динамически загружаемые компоновочные блоки
Из предыдущей главы вы узнали о том, как среда CLR использует информацию манифеста компоновочного блока при зондировании компоновочных блоков по внешним ссылкам. Все это, конечно, хорошо, но во многих случаях бывает необходимо "на лету" загрузить компоновочный блок программными средствами, а записей о соответствующем компоновочном блоке в манифесте нет. Формально загрузка внешних компоновочных блоков по запросу называется динамической загрузкой.
В рамках System.Reflection определяется класс, имя которого Assembly. Используя этот тип, можно динамически загрузить любой компоновочный блок, а также выяснить его свойства. Используя тип Assembly, можно динамически загружать приватные и общедоступные компоновочные блоки, размещенные в любом месте системы. Класс Assembly предлагает методы (в частности, Load() и LoadFrom()), позволяющие программными средствами получать информацию, аналогичную той, которая содержится в файле *.config клиента.
Для примера использования динамической загрузки создайте новое консольное приложение с именем ExternalAssemblyReflector. Вашей задачей является построение метода Main(), запрашивающего понятное имя компоновочного блока для динамической загрузки. Ссылка Assembly будет передана вспомогательному методу DisplayTypes(), который просто напечатает имена всех, классов, интерфейсов, структур, перечней и делегатов соответствующего компоновочного блока. Необходимый программный код выглядит довольно просто.
using System;
using System.Reflection;
using System.IO; // Для определения FileNotFoundException.
namespace ExternalAssemblyReflector {
class Program {
static void DisplayTypesInAsm(Assembly asm) {
Console.WriteLine("n*** Типы компоновочного блока ***");
Console.WriteLine("-› {0}", asm.FullName);
Type[] types = asm.GetTypes();
foreach (Type t in types) Console.WriteLine("Тип: {0}", t);
Console.WriteLine(");
}
static void Main(string[] args) {
Console.WriteLine("*** Обзор внешних компоновочных блоков ***");
string asmName = ";
bool userIsDone = false;
Assembly asm = null;
do {
Console.WriteLine("nВведите имя компоновочного блока");
Console.Write("или нажмите Q для выхода из приложения:");
// Получение имени компоновочного блока.
asmName = Console.ReadLine();
// Желает ли пользователь завершить работу приложения?
if (asmName.ToUpper() == "Q") {
userIsDone = true;
break;
}
// Попытка загрузить компоновочный блок.
try {
asm = Assembly.Load(asmName);
DisplayTypesInAsm(asm);
} catch {
Console.WriteLine("Извините, компоновочный блок не найден.");
}
} while (userIsDone);
}
}
}
Обратите внимание на то, что статическому методу Assembly.Load() передается только понятное имя компоновочного блока, который вы хотите загрузить в память. Поэтому, чтобы получить отображение CarLibrary.dll с помощью этой программы, перед ее выполнением нужно скопировать двоичный файл CarLibrary.dll в каталог BinDebug приложения ExternalAssemblyReflector. После этого вывод программы будет аналогичен показанному на рис. 12.4.
Рис. 12.4. Отображение внешнего компоновочного блока CarLibrary
Замечание. Чтобы приложение ExternalAssemblyReflector было более гибким, следует загружать внешний компоновочный блок с помощью Assembsly.LoadFrom(), а не с помощью Assembly.Load(). Тогда вы сможете указать для соответствующего компоновочного блока абсолютный путь (например, C:MyAppMyAsm.dll).
Исходный код. Проект ExternalAssemblyReflector размещен в подкаталоге, соответствующем главе 12.
Отображение общедоступных компоновочных блоков
Как вы можете догадываться, метод Assembly.Load() является перегруженным. Один из вариантов метода Assembly.Load() позволяет указать значение параметра culture (для локализованных компоновочных блоков), а также номер версии и значение открытого ключа (для общедоступных компоновочных блоков).
Весь набор элементов, идентифицирующих компоновочный блок, называют дисплейным (или отображаемым) именем. По своему формату дисплейное имя представляет собой строку пар имен и значений, разделенных запятыми, которая начинается с понятного имени компоновочного блока и продолжается необязательными определениями (они могут указываться в любом порядке). Вот как выглядит соответствующий шаблон (в скобках указаны необязательные элементы).
Name (,Culture = код_языка) (,Version = _главный_номер.дополнительный_номер.номер_компоновки.номep_вapиaнтa) (,PublicKeyToken= код_открытого_ключа)
Значение PublicKeyToken = null в строке, определяющей дисплейное имя, указывает на то, что при связывании проверка строгого имени не требуется и его наличие у компоновочного блока не обязательно. Значений Culture = "" сообщает о необходимости использований значения кода локализации, принятого на машине по умолчанию, например:
// Загрузка CarLibrary версии 1.0.982.23972 с кодом локализации,
// используемым по умолчанию.
Assembly a = Assembly.Load(@"CarLibrary,Version=1.0.982.23972,PublicKeyToken=null,Culture=''");
Пространство имен System.Reflection предлагает также тип AssemblyName, который позволяет представить указанную выше информационную строку в объектной переменной. Обычно этот класс используется вместе с System.Version, являющимся объектным контейнером для номера версии компоновочного блока. Создав дисплейное имя, вы можете передать его перегруженному методу Assembly.Load().
// Использование AssemblyName для определения дисплейного имени.
AssemblyName asmName;
asmName = new AssemblyName();
asmName.Name = "CarLibrary";
Version v = new Version("1.0.982.23972");
asmName.Version = v;
Assembly a = Assembly.Load(asmName);
Чтобы загрузить общедоступный компоновочный блок из GAC, параметр Assembly.Load() должен указать значение publickeytoken. Предположим, на-пример, что вы хотите загрузить компоновочный блок System.Windows.Forms.dll версии 2.0.0.0, предлагаемый библиотеками базовых классов .NET. Поскольку число типов в этом компоновочном блоке очень велико, следующее приложение выводит имена только первых 20 типов.
using System;
using System.Reflection;
using System.IO;
namespace SharedAsmReflector {
public class SharedAsmReflector {
private static void DisplayInfo(Assembly a) {
Console.WriteLine("***** Информация о компоновочном блоке *****");
Console.WriteLine("Загружен из GAC? {0}", a.GlobalAssemblyCache);
Console.WriteLine("Имя: {0}", a.GetName().Name);