Спецификация CTS поддерживает создание конструкторов как уровня экземпляра, так и уровня класса (статических). В CIL конструкторы уровня экземпляра представляются с использованием лексемы .ctor
.cctor (class constructor — конструктор класса). Обе лексемы CIL должны сопровождаться атрибутами rtspecialname (return type special name — специальное имя возвращаемого типа) и specialname. Упомянутые атрибуты применяются для обозначения специфической лексемы CIL, которая может трактоваться уникальным образом в любом отдельно взятом языке .NET Core. Например, в языке C# конструкторы не определяют возвращаемый тип, но в CIL возвращаемым значением конструктора на самом деле является void:.class public MyBaseClass
{
.field private string stringField
.field private int32 intField
.method public hidebysig specialname rtspecialname
instance void .ctor(string s, int32 i) cil managed
{
// Добавить код реализации...
}
}
Обратите внимание, что директива .ctor
instance (поскольку конструктор не статический). Атрибуты cil managed указывают на то, что внутри данного метода содержится код CIL, а не неуправляемый код, который может использоваться при выполнении запросов Р/Invoke.Определение свойств в CIL
Свойства и методы также имеют специфические представления в CIL. В качестве примера модифицируйте класс MyBaseClass
TheString, написав следующий код CIL (обратите внимание на применение атрибута specialname):.class public MyBaseClass
{
...
.method public hidebysig specialname
instance string get_TheString() cil managed
{
// Добавить код реализации...
}
.method public hidebysig specialname
instance void set_TheString(string 'value') cil managed
{
// Добавить код реализации...
}
.property instance string TheString()
{
.get instance string
MyNamespace.MyBaseClass::get_TheString()
.set instance void
MyNamespace.MyBaseClass::set_TheString(string)
}
}
В терминах CIL свойство отображается на пару методов, имеющих префиксы get_
set_. В директиве .property используются связанные директивы .get и .set для отображения синтаксиса свойств на подходящие "специально именованные" методы.На заметку!
Обратите внимание, что входной параметр методаset в свойстве помещен в одинарные кавычки и представляет имя лексемы, которая должна применяться в правой части операции присваивания внутри области определения метода.Определение параметров членов
Коротко говоря, параметры в CIL указываются (более или менее) идентично тому, как это делается в С#. Например, каждый параметр определяется путем указания его типа данных, за которым следует имя параметра. Более того, подобно C# язык CIL позволяет определять входные, выходные и передаваемые по ссылке параметры. Вдобавок в CIL допускается определять массив параметров (соответствует ключевому слову params
Чтобы проиллюстрировать процесс определения параметров в низкоуровневом коде CIL, предположим, что необходимо построить метод, который принимает параметр int32
int32 (по ссылке), параметр [System.Runtime.Extensions]System.Collection.ArrayList и один выходной параметр (типа int32). В C# метод выглядел бы примерно так:public static void MyMethod(int inputInt,
ref int refInt, ArrayList ar, out int outputInt)
{
outputInt = 0; // Просто чтобы удовлетворить компилятор C#...
}
После отображения метода MyMethod()
&), который дополняет лежащий в основе тип данных (int32 &).Выходные параметры также снабжаются суффиксом &
[out] языка CIL. Вдобавок если параметр относится к ссылочному типу ([System.RuntimeExtensions]System.Collections.ArrayList), то перед типом данных указывается лексема class (не путайте ее с директивой .class):