Язык программирования 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
и т.д.
Поделиться с друзьями: