Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Троелсен Э. -> "С# и платформа .NET. Библиотека программиста" -> 138

С# и платформа .NET. Библиотека программиста - Троелсен Э.

Троелсен Э. С# и платформа .NET. Библиотека программиста — СПб.: Питер, 2004. — 796 c.
ISBN 5-318-00750-3
Скачать (прямая ссылка): cplatforma2004.pdf
Предыдущая << 1 .. 132 133 134 135 136 137 < 138 > 139 140 141 142 143 144 .. 320 >> Следующая

Как мы видим, создание сборки начинается с присвоения ей имени и номера версии при помощи класса AssOTblyNriiHE'. Далее мы создаем сборку в памяти, используя для этого тип AppCcina і n (про него рассказывалось в главе 6). Обратите Bi і пма* шс. что вспомогательная функция CreatefiyAsinu принимает объект типа АррСогпа:':
// Создаем сборку в памяти
AssemblyBuilder assembly = currAppDomain.DefineDynnmicAssemblytassemblyNfldie.
AssemblyBui"IderAccess.Save):
При вызове AppDomai п. Defi neDynciffii cAssembl у() мы должны указать режим доступа — один из трех, представленных в табл. 7.4.
Таблица 7.4. Значения перечисления AssemblyBurderAccess Значение Для чего оно используется
Run Динамическая сборка должна быть запущена на выполнение, но не сохранена
iRunAndSave Запустить на выполнение и сохранить Save Сохранить, не запуская
Далее мы должны вставить в сборку модуль. Наша сборка состоит из единственного модуля, поэтому наша задача упрощается. Если же нам потребуется создать многофайловую динамическую сборку, нам придется использовать метод DefinsljynaiincModulc1!) с еще одним параметром, представляющим имя указан-
Применение динамических сборок 331
модуля (например, При создании сборки имя мо-
дуля (оно же — имя двоичного файла) совпадает с именем самой сборки:
// Создание однофайловой динамической сборки
ModuleBuilder module = assembly.DefineDynamicModuleCMyAssembly". "MyAssembly.dll"};
Используя метод Modul eBui 1 der. Def і neTy ре (), мы можем вставить в модуль класс, структуру или интерфейс, а затем получить обратно ссылку на объект TypeBui lder, который представляет новый тип (в нашем случае это класс HeI 1 oWorld). После этого
мы можем добавить в созданный класс новый член:
t
II Определяем класс "HelloWorld"
TypeBuilder helloWorldClass - module.Def і neTypeCMyAssembly.HelloWorld".
TypeAttri butes.Public):
Il Определяем переменную Msg
FieldBuilder msgField = helloWorldClass.DefineFieldC'Msg".
Type.GetTypet"System.String"). FieldAttributes.Private);
При создании конструктора класса нам придется прибегнуть к использованию кода IL сыром виде». Код IL, который помещается в реализацию конструктора при помощи метода Efif U} класса ILGenerator, ответственен за присно -ние принимаемого конструктором значения внутренней переменной Msg. Для метода F.'m 11 () используется перечисление Opcodes (от Operation С odes — коды операции), которое определяет допустимые команды IL. Например, OpCodes. Ret означает возврат после вызова метода, — собственно присвоение
значения переменной и т. п. Логика создания конструктора выглядит следующим образом:
// Создам конструктор класса HelloWorld Туре[] costructorArgs = new Typed]: constructorArgsfO] = type,GetType("System.String");
ConstructorBuilder constructor =
hel1oWorldClass.Defі neConstructor(MethodAttributes.Publі с, CaI1 і ngConventi ons.Standard. constructorArgs):
ILGenerator constructorIL = constructor.GetILGeneratort);
con s t ructo r Ї L.Emi t(Opcodes.Lda rg_0);
Type objectClass = Type.GetTypeCSysteiK.Object");
=
// Прплзколяг! вызов конструктора базового класса constructorIL.Emit(OpCodes.Ca11, superCpnstructor):
Il Загружаем указатель this для объекта в стек constructorIL.EmI UOpCodes.Ldarg_0):
// Загружаем константное 4-Сайтовое значение 0 в виртуальный стек
constructorIL.Emit(OpCodes.Ldarg_l);
// Присезиаде* значение msgF'eld
constructor1L.Emit(Opcodes.Stf1d. msgField):
// йогера' из метода
const ructorlt.Em і t(OpCodes.Ret);
332 Глава 7 * Рефлексия типов и с использованием атрибутов
Для создания метода SayHel 1 о() применяется тот же самый набор средств: // Создаем нетод SayHelIoО
MethodBuilder sayHiMethod - hellokorldClass.Definer'ethodC'SayHello".
HethodAttributer..Public, null, null): iaetfrodll = say41Hethcd.GetlLGenerator():
Il Выводим строку на системную консоль methodIL.EmitWriteLine("Hello there!"): methodlL. EmittOpCodes. Ret);
Таким образом, мы создали метод, помеченный как public (при помощи Me-гіімЛіД у ['ид (3S Puhl 1 с), который не принимает параметров и ничего не возвращает (обратите внимание на значения null при вызове DefineMethodt)) Метод Ennt-Kr іtetі ne( і. который определен в классе і LGenera -.or,умеет выводить строки в стандартный канал вывода очень быстро и эффективно. Он помещен здесь как пример возможностей при использовании «голого» IL.
Как использовать динамическую сборку
Код, который позволяет создавать и сохранять нашу сборку, у нас уже есть. Нам осталось лишь обеспечить вызов этого кода. Этим будет заниматься еще один класс — AsmReauer. В методе Main() будет создаваться объект класса.і г., который затем будет передаваться методу Creete^yAsntU). После возврата из этого метода мы применим позднее для загрузки только что созданной
сборки в память и вызова обоих методов класса >¦d 1 и'л'игId. В нижеприведенном
коде обратите особое внимание на то, как можно вызвать перегруженный конструктор и передать ему параметр, а также — как используется значение, возвращаемое SetHsgO:
namespace OyrAsmfju і 1 der {
Предыдущая << 1 .. 132 133 134 135 136 137 < 138 > 139 140 141 142 143 144 .. 320 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100