Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

"theMessage",

Type.GetType("System.String"),

attributes: FieldAttributes.Private);

// Создать специальный конструктор.

Type[] constructorArgs = new Type[1];

constructorArgs[0] = typeof(string);

ConstructorBuilder constructor =

helloWorldClass.DefineConstructor(

MethodAttributes.Public,

CallingConventions.Standard,

constructorArgs);

ILGenerator constructorIl = constructor.GetILGenerator;

constructorIl.Emit(OpCodes.Ldarg_0);

Type objectClass = typeof(object);

ConstructorInfo superConstructor =

objectClass.GetConstructor(new Type[0]);

constructorIl.Emit(OpCodes.Call, superConstructor);

constructorIl.Emit(OpCodes.Ldarg_0);

constructorIl.Emit(OpCodes.Ldarg_1);

constructorIl.Emit(OpCodes.Stfld, msgField);

constructorIl.Emit(OpCodes.Ret);

//
Создать стандартный конструктор.

helloWorldClass.DefineDefaultConstructor(

MethodAttributes.Public);

// Создать метод GetMsg.

MethodBuilder getMsgMethod = helloWorldClass.DefineMethod(

"GetMsg",

MethodAttributes.Public,

typeof(string),

null);

ILGenerator methodIl = getMsgMethod.GetILGenerator;

methodIl.Emit(OpCodes.Ldarg_0);

methodIl.Emit(OpCodes.Ldfld, msgField);

methodIl.Emit(OpCodes.Ret);

// Создать метод SayHello.

MethodBuilder sayHiMethod = helloWorldClass.DefineMethod(

"SayHello", MethodAttributes.Public, null, null);

methodIl = sayHiMethod.GetILGenerator;

methodIl.EmitWriteLine("Hello from the HelloWorld class!");

methodIl.Emit(OpCodes.Ret);

// Выпустить класс HelloWorld.

helloWorldClass.CreateType;

return builder;

}

Выпуск сборки и набора модулей

Тело метода начинается с установления минимального набора характеристик сборки с применением типов

AssemblyName
и
Version
(определенных в пространстве имен
System.Reflection
). Затем производится получение объекта типа
AssemblуBuilder
через статический метод
AssemblyBuilder.DefineDynamicAssembly
.

При вызове метода

DefineDynamicAssembly
должен быть указан режим доступа к определяемой сборке, наиболее распространенные значения которого представлены в табл. 19.9.

Следующая

задача связана с определением набора модулей (и имени) для новой сборки. Метод
DefineDynamicModule
возвращает ссылку на действительный объект типа
ModuleBuilder
:

// Создать новую сборку.

var builder = AssemblyBuilder.DefineDynamicAssembly(

assemblyName,AssemblyBuilderAccess.Run);

Роль типа ModuleBuilder

Тип

ModuleBuilder
играет ключевую роль во время разработки динамических сборок. Как и можно было ожидать,
ModuleBuilder
поддерживает несколько членов, которые позволяют определять набор типов, содержащихся внутри модуля (классы, интерфейсы, структуры и т.д.), а также набор встроенных ресурсов (таблицы строк, изображения и т.п.). В табл. 19.10 описаны два метода, относящиеся к созданию. (Обратите внимание, что каждый метод возвращает объект связанного типа, который представляет тип, подлежащий созданию.)

Основным членом класса

ModuleBuilder
является метод
DefineType
. Кроме указания имени типа (в виде простой строки) с помощью перечисления
System.Reflection.TypeAttributes
можно описывать формат этого типа. В табл. 19.11 приведены избранные члены перечисления
TypeAttributes
.

Выпуск типа HelloClass и строковой переменной-члена

Теперь, когда вы лучше понимаете роль метода

ModuleBuilder.CreateType
, давайте посмотрим, как можно выпустить открытый тип класса
HelloWorld
и закрытую строковую переменную:

// Определить открытый класс по имени HelloWorld.

TypeBuilder helloWorldClass =

module.DefineType("MyAssembly.HelloWorld",

TypeAttributes.Public);

// Определить закрытую переменную-член типа String по имени theMessage.

FieldBuilder msgField = helloWorldClass.DefineField(

"theMessage",

Type.GetType("System.String"),

attributes: FieldAttributes.Private);

Обратите внимание, что метод

TypeBuilder.DefineField
предоставляет доступ к объекту типа
FieldBuilder
. В классе
TypeBuilder
также определены дополнительные методы, которые обеспечивают доступ к другим типам "построителей". Например, метод
DefineConstructor
возвращает объект типа
ConstructorBuilder
, метод
DefineProperty
— объект типа
PropertyBuilder
и т.д.

Поделиться с друзьями: