Определение пользовательских атрибутов в Cil
Вопрос
Что такое синтаксис для определения литерала массива в CIL для целей украшения участника с пользовательским атрибутом?
Я пишу несколько .NET CODE в CIL (используя ILASM.exe, чтобы скомпилировать его), и мне нужно украсить метод с помощью пользовательского атрибута. Конструктор для этого атрибута принимает массив целых чисел в качестве его единственного параметра. Как я могу сделать это в Cil?
Это подпись конструктора пользовательского атрибута (я не могу его изменить):
public FooAttribute(int[] values) {
// some hidden constructor stuff
}
Вот как я бы украсил свой метод, если я пишу в C # (но я не могу):
[Foo(new int[] {1, 2, 3, 4})]
public string Bar() {
return "Some text";
}
Использование ILDasm.exe, чтобы посмотреть на скомпилированное C # (чтобы попытаться понять по обратным инженерии) дает мне уродливой и непригодный двоичный литерал. Вместо этого я пытался использовать Reflector.net, и он выглядит намного лучше, но Ilasm.exe бросает ошибку синтаксиса по ключевому слову «Новый», поэтому я не могу его использовать:
.custom instance void SomeNamespace.FooAttribute::.ctor(int32[]) = { new int32[int32(4)] { int32(1), int32(2), int32(3), int32(4) } }
Решение
Трудно угадать, какова может быть ваша проблема. Если я применю этот атрибут в метод программы .test (), я получу это:
.method private hidebysig static void Test() cil managed
{
.custom instance void ConsoleApplication1.FooAttribute::.ctor(int32[]) = ( 01 00 04 00 00 00 01 00 00 00 02 00 00 00 03 00
00 00 04 00 00 00 00 00 )
// Code size 2 (0x2)
.maxstack 8
IL_0000: nop
IL_0001: ret
} // end of method Program::Test
Запустите это через Ilasm.exe, нет проблем. Обратите внимание, как значения элемента массива (прокрутите окно фрагмента вправо, чтобы увидеть их) уже преобразуются в формат, необходимый для встраивания их в таблицу данных конструктора атрибута. Bitconverter.getbytes () может получить часть этой работы. Документ ECMA должен иметь необходимый формат этого данных.