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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 353 354 355 356 357 358 359 360 361 ... 642

ConstructorBuilder myCtorBuilder = /* */;

ILGenerator myCILGen = myCtorBuilder.GetILGenerator();

Имея объект ILGenerator, с помощью его методов можно выпускать низкоуровневые коды операций CIL. Некоторые (но не все) методы ILGenerator кратко описаны в табл. 19.8.

Основным методом класса ILGenerator является Emit(), который работает в сочетании с типом System.Reflection.Emit.Opcodes. Как упоминалось ранее в главе, данный тип открывает доступ к множеству полей только для чтения, которые отображаются на низкоуровневые коды операций CIL. Полный набор этих членов документирован в онлайновой справочной системе, и далее в главе вы неоднократно встретите примеры их использования.

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

Чтобы проиллюстрировать процесс определения сборки .NET Core во время выполнения, давайте рассмотрим процесс создания однофайловой динамической сборки по имени MyAssembly.dll.

Внутри модуля находится класс HelloWorld, который поддерживает стандартный конструктор и специальный конструктор, применяемый для присваивания значения закрытой переменной-члена (theMessage) типа string. Вдобавок в классе HelloWorld имеется открытый метод экземпляра под названием SayНеllo(), который выводит приветственное сообщение в стандартный поток ввода-вывода, и еще один метод экземпляра по имени GetMsg(), возвращающий внутреннюю закрытую строку. По существу мы собираемся программно сгенерировать следующий тип класса:

<b>// Этот класс будет создаваться во время выполнения с использованием</b>

<b>// пространства имен System.Reflection.Emit.</b>

public class HelloWorld

{

  private string theMessage;

  HelloWorld() {}

  HelloWorld(string s) {theMessage = s;}

  public string GetMsg() {return theMessage;}

  public void SayHello()

  {

    System.Console.WriteLine(&quot;Hello from the HelloWorld class!&quot;);

  }

}

Создайте новый проект консольного приложения по имени MyAsmBuilder и добавьте NuGet-пакет System.Reflection.Emit. Импортируйте в него пространства имен System.Reflection и System.Reflection.Emit. Определите в классе Program статический метод по имени CreateMyAsm(). Этот единственный метод будет отвечать за решение следующих задач:

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

• определение характеристик динамической сборки (имя, версия и т.п.);

• реализация типа HelloClass;

• возвращение вызывающему методу объекта AssemblyBuilder.

Ниже приведен полный код, а затем его анализ:

static AssemblyBuilder CreateMyAsm()

{

<b>  // Установить общие характеристики сборки.</b>

  AssemblyName assemblyName = new AssemblyName

  {

    Name = &quot;MyAssembly&quot;,

    Version = new Version(&quot;1.0.0.0&quot;)

  };

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

  var builder = AssemblyBuilder.DefineDynamicAssembly(

    assemblyName,AssemblyBuilderAccess.Run);

<b>  // Определить имя модуля.</b>

  ModuleBuilder module =

    builder.DefineDynamicModule(&quot;MyAssembly&quot;);

<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);

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

  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);

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

Оставить комментарий