Формат файла .NET – внутреннее устройство сигнатур (часть 1) - PropertySig
ОГЛАВЛЕНИЕ
4.2 PropertySig
Сигнатура PropertySig индексируется столбцом Property.Type, она хранит информацию о свойстве – то есть число параметров, передаваемых свойству, чтобы получить данные, ноль или больше специальных модификаторов, тип возвращаемого значения, тип каждого переданного параметра. Но в сигнатуре PropertySig появилась одна новая вещь, а именно – флаг HASTHIS (из постоянного значения 0x20), он показывает, передает ли во время выполнения вызванный метод указатель на целевой объект в качестве своего первого аргумента (указатель this). Флаг HASTHIS устанавливается, когда свойство (фактически, его установщик и получатель) является экземпляром или виртуальным, и не устанавливается, когда свойство (установщик и получатель) является статическим. Флаг (если установлен) - ORed вместе со значением пролога сигнатуры. Ниже показана полная схема синтаксиса для данной сигнатуры.
Рисунок 5. Схема синтаксиса сигнатуры PropertySig
Пример 1
Первый пример тривиальный: мы создали одно свойство экземпляра типа int32, как показано ниже.
// Полный исходник: PropertySig\1.cs
// Бинарный файл: PropertySig\1.dll
// (...)
public int TestProperty { get; set; }
Сигнатура начинается со смещения 0x001A в куче #Blob.
Смещение |
Значение |
Что означает |
0x1A |
0x03 |
Размер сигнатуры |
0x1B |
0x28 |
Пролог ORed с константой HASTHIS, так как 0x20 OR 0x08 = 0x28. |
0x1C |
0x00 |
Количество параметров, передаваемых методу-получателю свойства, смотрите рисунок 5 выше. |
0x1D |
0x08 |
Тип возвращаемого значения свойства (int32), смотрите константы. |
Пример 2
Данный пример немного сложней, так как он использует индексированное свойство, возвращающее(го) разное значение в зависимости от параметров, переданных свойству, и, как видно ниже, такой тип свойства не имеет никакого имени (в C#), но в таблице метаданных Field оно всегда объявляется как Item(элемент). Можно определить только одно индексированное свойство на каждый класс/структуру, но его можно перегружать.
// Полный исходник: PropertySig\2.cs
// Бинарный файл: PropertySig\2.dll
// (...)
public int this [int Param1, string Param2]
{
get { return 0; }
set { }
}
Сигнатура ранее упомянутого поля хранится со смещением 0x001B в #Blob и описана в таблице ниже.\
Смещение |
Значение |
Что означает |
0x1B |
0x05 |
Размер сигнатуры |
0x1C |
0x28 |
Свойство имеет тип экземпляра, поэтому вновь пролог сигнатуры объединен с помощью OR с константой HASTHIS. |
0x1D |
0x02 |
Количество параметров, передаваемых методу-получателю свойства, смотрите рисунок 5 выше. |
0x1E |
0x08 |
Тип возвращаемого значения свойства (int32), смотрите константы. |
0x1F |
0x08 |
Тип значения первого параметра свойства (int32), смотрите константы. |
0x20 |
0x0E |
Тип значения второго параметра свойства (string), смотрите константы. |
Пример 3
В этом примере мы попытаемся отключить флаг HASTHIS, объявив свойство как статическое.
// Полный исходник: PropertySig\3.cs
// Бинарный файл: PropertySig\3.dll
// (...)
public class TestClas
{
public static int TestProperty { get; set; }
}
На этот раз вышеуказанная сигнатура свойства начинается со смещения 0x001A в #Blob.
Смещение |
Значение |
Что означает |
0x1A |
0x03 |
Размер сигнатуры |
0x1B |
0x08 |
Постоянное значение пролога (только). |
0x1C |
0x00 |
Количество параметров, передаваемых методу-получателю свойства, смотрите рисунок 5 выше. |
0x1D |
0x08 |
Тип возвращаемого значения свойства (int32), смотрите константы. |