2010-06-11 245 views
4

爲了裝飾具有自定義屬性的成員,在CIL中定義數組文字的語法是什麼?在CIL中定義自定義屬性

我在CIL中編寫了一些.NET代碼(使用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 2010-06-11 15:22:45

+2

我看不懂。 Ecma 335,分區2,第21章說你不能。 Ctor數據必須以字節爲單位。這也許可以解釋爲什麼你在製作其他作品時遇到麻煩?不要認爲反彙編器顯示的格式符合標準。 – 2010-06-11 15:46:55

+0

確實,ECMA標準沒有提到我用於構造函數參數的簡單格式。 ilasm.exe與幾種基本類型(字符串,整數,布爾型,類型等)沒有問題,但它看起來是非標準的。 – Jono 2010-06-14 09:03:50