Как упоминалось ранее, для определения конструктора текущего типа можно применять метод
TypeBuilder.DefineConstructor
. Однако когда дело доходит до реализации конструктора
HelloClass
, в тело конструктора необходимо вставить низкоуровневый код CIL, который будет отвечать за присваивание входного параметра внутренней закрытой строке. Чтобы получить объект типа
ILGenerator
, понадобится вызвать метод
GetILGenerator
из соответствующего типа "построителя" (в данном случае
ConstructorBuilder
).
Помещение
кода CIL в реализацию членов осуществляется с помощью метода
Emit
класса
ILGenerator
. В самом методе
Emit
часто используется тип класса
Opcodes
, который открывает доступ к набору кодов операций CIL через свойства только для чтения. Например, свойство
Opcodes.Ret
обозначает возвращение из вызова метода
.Opcodes.Stfid
создает присваивание значения переменной-члену, a
Opcodes.Call
применяется для вызова заданного метода (конструктора базового класса в данном случае). Итак, логика для реализации конструктора будет выглядеть следующим образом:
// Создать специальный конструктор, принимающий
// единственный аргумент типа string.
Type[] constructorArgs = new Type[1];
constructorArgs[0] = typeof(string);
ConstructorBuilder constructor =
helloWorldClass.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
constructorArgs);
// Выпустить необходимый код CIL для конструктора.
// Загрузить входной аргумент в виртуальный стек и сохранить его в msgField
constructorIl.Emit(OpCodes.Stfld, msgField);
constructorIl.Emit(OpCodes.Ret);
Как вам теперь уже известно, в результате определения специального конструктора для типа стандартный конструктор молча удаляется. Чтобы снова определить конструктор без аргументов, нужно просто вызвать метод
DefineDefaultConstructor
типа
TypeBuilder
:
// Создать стандартный конструктор.
helloWorldClass.DefineDefaultConstructor(
MethodAttributes.Public);
Выпуск
метода SayHello
В заключение давайте исследуем процесс выпуска метода
SayHello
. Первая задача связана с получением объекта типа
MethodBuilder
из переменной
helloWorldClass
. После этого можно определить сам метод и получить внутренний объект типа