Язык программирования C#9 и платформа .NET5
Указание ссылок на внешние сборки в CIL
Скопируйте файлы
иglobal.jsonиз предыдущего примера в новый каталог проекта. Создайте новый файл проекта по имениNuGet.config, содержимое которого показано ниже:CILTypes.ilproj<Project Sdk="Microsoft.NET.Sdk.IL"><PropertyGroup><TargetFramework>net5.0</TargetFramework><MicrosoftNetCoreIlasmPackageVersion>5.0.0-preview.1.20120.5</MicrosoftNetCoreIlasmPackageVersion><ProduceReferenceAssembly>false</ProduceReferenceAssembly></PropertyGroup></Project>Затем создайте в текстовом редакторе новый файл по имени
. Первой задачей в проекте CIL является перечисление внешних сборок, которые будут задействованы текущей сборкой. В рассматриваемом примере применяются только типы, находящиеся внутри сборкиCILTypes.il. В новом файле понадобится указать директивуSystem.Runtime.dllс уточняющим атрибутом.assembly. При добавлении ссылки на сборку со строгим именем, подобнуюexternal, также должны быть указаны директивыSystem.Runtime.dllи.publickeytoken:.ver.assembly extern System.Runtime{.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ).ver 5:0:0:0}Определение текущей сборки в CIL
Следующее действие заключается в определении создаваемой сборки с использованием директивы
. В простейшем случае сборка может быть определена за счет указания дружественного имени двоичного файла:.assembly<b>// Наша сборка.</b>.assembly CILTypes{}Хотя такой код действительно определяет новую сборку .NET Core, обычно внутрь объявления будут помещаться дополнительные директивы. В рассматриваемом примере определение сборки необходимо снабдить номером версии 1.0.0.0 посредством директивы
(обратите внимание, что числа в номере версии отделяются друг от друга двоеточиями, а не точками, как принято в С#):.ver<b>// Наша сборка.</b>.assembly CILTypes{<b> .ver 1:0:0:0</b>}Из-за того, что сборка
является однофайловой, ее определение завершается с применением следующей директивыCILTypes, которая обозначает официальное имя двоичного файла .NET Core, т.е..module:CILTypes.dll// Наша сборка.assembly CILTypes{.ver 1:0:0:0}// Модуль нашей однофайловой сборки..module CILTypes.dllКроме
и.assemblyсуществуют директивы CIL, которые позволяют дополнительно уточнять общую структуру создаваемого двоичного файла .NET Core. В табл. 19.1 перечислены некоторые наиболее распространенные директивы уровня сборки..moduleОпределение пространств имен в CIL
Определив внешний вид и поведение сборки (а также обязательные внешние ссылки), вы можете создать пространство имен .NET Core (
), используя директивуMyNamespace:.namespace<b>// Наша сборка имеет единственное пространство имен.</b>.namespace MyNamespace {}Подобно C# определения пространств имен CIL могут быть вложены в другие пространства имен. Хотя здесь нет нужды определять корневое пространство имен, ради интереса посмотрим, как создать корневое пространство имен
:MyCompany.namespace MyCompany{.namespace MyNamespace {}}Как и С#, язык CIL позволяет определить вложенное пространство имен следующим образом:
<b>// Определение вложенного пространства имен.</b>.namespace MyCompany.MyNamespace {}Определение типов классов в CIL
Пустые пространства имен не особо интересны, поэтому давайте рассмотрим процесс определения типов классов в CIL. Для определения нового типа класса предназначена директива
. Тем не менее, эта простая директива может быть декорирована многочисленными дополнительными атрибутами, уточняющими природу типа. В целях иллюстрации добавим в наше пространство имен открытый класс под названием.class. Как и в С#, если базовый класс явно не указан, то тип автоматически становится производным отMyBaseClass:System.Object.namespace MyNamespace{<b> // Предполагается базовый класс System.Object.</b>.class public MyBaseClass {}}При построении типа, производного не от класса
, применяется атрибутSystem.Object. Для ссылки на тип, определенный внутри той же самой сборки, язык CIL требует использования полностью заданного имени (однако если базовый тип находится внутри той же самой сборки, то префикс в виде дружественного имени сборки можно не указывать). Следовательно, демонстрируемая ниже попытка расширенияextendsв результате дает ошибку на этапе компиляции:MyBaseClass
