Категории
Самые читаемые
ChitatKnigi.com » 🟢Компьютеры и Интернет » Базы данных » Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Читать онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
1 ... 354 355 356 357 358 359 360 361 362 ... 642
Перейти на страницу:

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать

  constructorIl.Emit(OpCodes.Stfld, msgField);

  constructorIl.Emit(OpCodes.Ret);

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

  helloWorldClass.DefineDefaultConstructor(

    MethodAttributes.Public);

<b>  // Создать метод GetMsg().</b>

  MethodBuilder getMsgMethod = helloWorldClass.DefineMethod(

    &quot;GetMsg&quot;,

    MethodAttributes.Public,

    typeof(string),

    null);

  ILGenerator methodIl = getMsgMethod.GetILGenerator();

  methodIl.Emit(OpCodes.Ldarg_0);

  methodIl.Emit(OpCodes.Ldfld, msgField);

  methodIl.Emit(OpCodes.Ret);

<b>  // Создать метод SayHello().</b>

  MethodBuilder sayHiMethod = helloWorldClass.DefineMethod(

    &quot;SayHello&quot;, MethodAttributes.Public, null, null);

  methodIl = sayHiMethod.GetILGenerator();

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

  methodIl.Emit(OpCodes.Ret);

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

  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 описаны два метода, относящиеся к созданию. (Обратите внимание, что каждый метод возвращает объект связанного типа, который представляет тип, подлежащий созданию.)

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

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

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

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

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

TypeBuilder helloWorldClass =

  module.DefineType(&quot;MyAssembly.HelloWorld&quot;,

  TypeAttributes.Public);

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

FieldBuilder msgField = helloWorldClass.DefineField(

  &quot;theMessage&quot;,

  Type.GetType(&quot;System.String&quot;),

  attributes: FieldAttributes.Private);

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

Выпуск конструкторов

Как упоминалось ранее, для определения конструктора текущего типа можно применять метод TypeBuilder.DefineConstructor(). Однако когда дело доходит до реализации конструктора HelloClass, в тело конструктора необходимо вставить низкоуровневый код CIL, который будет отвечать за присваивание входного параметра внутренней закрытой строке. Чтобы получить объект типа ILGenerator, понадобится вызвать метод GetILGenerator() из соответствующего типа "построителя" (в данном случае ConstructorBuilder).

Помещение кода CIL в реализацию членов осуществляется с помощью метода Emit() класса ILGenerator. В самом методе Emit() часто используется тип класса Opcodes, который открывает доступ к набору кодов операций CIL через свойства только для чтения. Например, свойство Opcodes.Ret обозначает возвращение из вызова метода .Opcodes.Stfid создает присваивание значения переменной-члену, a Opcodes.Call применяется для вызова заданного метода (конструктора базового класса в данном случае). Итак, логика для реализации конструктора будет выглядеть следующим образом:

1 ... 354 355 356 357 358 359 360 361 362 ... 642
Перейти на страницу:
Отывы о книге
Открыть боковую панель
Комментарии
Ксения
Ксения 25.01.2025 - 12:30
Неплохая подборка книг. Прочитаю все однозначно.
Jonna
Jonna 02.01.2025 - 01:03
Страстно🔥 очень страстно
Ксения
Ксения 20.12.2024 - 00:16
Через чур правильный герой. Поэтому и остался один
Настя
Настя 08.12.2024 - 03:18
Прочла с удовольствием. Необычный сюжет с замечательной концовкой
Марина
Марина 08.12.2024 - 02:13
Не могу понять, где продолжение... Очень интересная история, хочется прочесть далее