Definindo atributos personalizados em CIL
Pergunta
Qual é a sintaxe para definir uma matriz literal em CIL para fins de decorar um membro com um atributo personalizado?
Estou escrevendo algum código .NET no CIL (usando ilasm.exe para compilá -lo) e preciso decorar um método com um atributo personalizado. O construtor desse atributo toma uma variedade de números inteiros como seu único parâmetro. Como posso fazer isso em CIL?
Esta é a assinatura do construtor do atributo personalizado (não posso alterá -lo):
public FooAttribute(int[] values) {
// some hidden constructor stuff
}
É assim que eu decoraria meu método se estivesse escrevendo em C# (mas não posso):
[Foo(new int[] {1, 2, 3, 4})]
public string Bar() {
return "Some text";
}
O uso do ildasm.exe para olhar para o C# compilado (para tentar entender por engenharia reversa) me dá um literal binário feio e inutilizável. Eu tentei usar o reflettor.net e ele parece muito melhor, mas o ilasm.exe lança um erro de sintaxe na palavra -chave "new", para que eu não possa usá -lo:
.custom instance void SomeNamespace.FooAttribute::.ctor(int32[]) = { new int32[int32(4)] { int32(1), int32(2), int32(3), int32(4) } }
Solução
Difícil adivinhar qual pode ser o seu problema. Se eu aplicar este atributo a um método do programa.test (), entendo isso:
.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
Execute isso através do ilasm.exe, sem problemas. Observe como os valores dos elementos da matriz (role a janela Snippet para a direita para vê -los) já estão convertidos no formato necessário para incorporá -los na tabela de dados do construtor de atributos. BitConverter.getBytes () pode ser feito parte desse trabalho. O documento da ECMA deve ter o formato necessário desses dados.