Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
Шрифт:
Интервал:
Закладка:
Нововведением .NET 5 стало то, что ваше приложение может быть сведено до единственного файла, который запускается напрямую. Хотя такой единственный файл выглядит и действует подобно собственному исполняемому модулю в стиле C++, его преимущество заключается в пакетировании. Он содержит все файлы, необходимые для выполнения вашего приложения и потенциально даже саму исполняющую среду .NET 5! Но помните о том, что ваш код по-прежнему выполняется в управляемом контейнере, как если бы он был опубликован в виде множества файлов.
Во-вторых, сборка содержит код CIL, который концептуально похож на байт-код Java тем, что не компилируется в специфичные для платформы инструкции до тех пор, пока это не станет абсолютно необходимым. Обычно "абсолютная необходимость" наступает тогда, когда на блок инструкций CIL (такой как реализация метода) производится ссылка с целью его применения исполняющей средой .NEIT Core.
В-третьих, сборки также содержат метаданные, которые детально описывают характеристики каждого "типа" внутри двоичного модуля. Например, если имеется класс по имени SportsCar, то метаданные типа представляют такие детали, как базовый класс SportsCar, указывают реализуемые SportsCar интерфейсы (если есть) и дают полные описания всех членов, поддерживаемых типом SportsCar. Метаданные .NET Core всегда присутствуют внутри сборки и автоматически генерируются компилятором языка.
Наконец, в-четвертых, помимо инструкций CIL и метаданных типов сами сборки также описываются с помощью метаданных, которые официально называются манифестом. Манифест содержит информацию о текущей версии сборки, сведения о культуре (используемые для локализации строковых и графических ресурсов) и список ссылок на все внешние сборки, которые требуются для надлежащего функционирования. Разнообразные инструменты, которые можно применять для исследования типов, метаданных и манифестов сборок, рассматриваются в нескольких последующих главах.
Роль языка CIL
Теперь давайте займемся детальными исследованиями кода CIL, метаданных типов и манифеста сборки. Язык CIL находится выше любого набора инструкций, специфичных для конкретной платформы. Например, приведенный далее код C# моделирует простой калькулятор. Не углубляясь пока в подробности синтаксиса, обратите внимание на формат метода Add() в классе Calc.
// Calc.cs
using System;
namespace CalculatorExamples
{
// Этот класс содержит точку входа приложения.
class Program
{
static void Main(string[] args)
{
Calc c = new Calc();
int ans = c.Add(10, 84);
Console.WriteLine("10 + 84 is {0}.", ans);
// Ожидать нажатия пользователем клавиши <Enter>
// перед завершением работы.
Console.ReadLine();
}
}
// Калькулятор С#.
class Calc
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390}){
public int Add(int addendl, int addend2)
{
return addendl + addend2;
}
}
}
Результатом компиляции такого кода будет файл *.dll сборки, который содержит манифест, инструкции CIL и метаданные, описывающие каждый аспект классов Calc и Program.
На заметку! В главе 2 будет показано, как использовать для компиляции файлов кода графические среды интегрированной разработки (integrated development environment — IDE), такие как Visual Studio Community.
Например, если вы выведете код IL из полученной сборки с помощью ildasm.exe (рассматривается чуть позже в главе), то обнаружите, что метод Add() был представлен в CIL следующим образом:
.method public hidebysig instance int32
Add(int32 addendl, int32 addend2) cil managed
{
// Code size 9(0x9)
// Размер кода 9(0x9)
.maxstack 2
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldarg.2
IL_0003: add
IL_0004: stloc.0
IL_0005: br.s IL_0007
IL_0007: ldloc.0
IL 0008: ret
} // end of method Calc::Add конец метода Calc::Add
Не беспокойтесь, если результирующий код CIL этого метода выглядит непонятным — в главе 19 будут описаны базовые аспекты языка программирования CIL. Важно понимать, что компилятор C# выпускает код CIL, а не инструкции, специфичные для платформы.
Теперь вспомните, что сказанное справедливо для всех компиляторов .NET. В целях иллюстрации создадим то же самое приложение на языке Visual Basic вместо С#:
' Calc.vb
Namespace CalculatorExample
Module Program
' Этот класс содержит точку входа приложения.
Sub Main(args As String())
Dim c As New Calc
Dim ans As Integer = c.Add(10, 84)
Console.WriteLine("10 + 84 is {0}", ans)
' Ожидать нажатия пользователем клавиши <Enter>
' перед завершением работы.
Console.ReadLine()
End Sub