2010-06-11 3 views
4

Каков синтаксис для определения литерала массива в CIL для целей украшения элемента с помощью настраиваемого атрибута?Определение пользовательских атрибутов в CIL

Я пишу некоторый код .NET в 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) } } 

ответ

3

трудно догадаться, что может быть ваша проблема. Если я применить этот атрибут к методу Program.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 должен иметь требуемый формат этих данных.

+0

Выход из ildasm (как вы показали выше) имеет массив, уже преобразованный в правильный формат, но это не требуется, и для других типов/аргументов их можно предоставить в формате: = { string('Hello, World!') bool(true) type(int32) type([System.Xml]System.Xml.XmlDocument) }, а не вынуждены предварительно форматировать их. – Jono

+2

Я не могу это прочитать. Ecma 335, раздел 2, глава 21 говорит, что вы не можете. Данные Ctor должны быть в байтах. Что, возможно, объясняет, почему у вас проблемы с работой над чем-то другим? Не допускайте, чтобы формат, показанный дизассемблером, соответствовал стандарту. –

+0

Действительно, стандарт ECMA ничего не говорит о простом формате, который я использовал для аргументов contructor. У ilasm.exe нет проблем с несколькими основными типами (строки, ints, bools, types и т. д.), но, похоже, они нестандартны. – Jono