2010-03-30 14 views
4

首先,這裏是C#代碼和反彙編IL:使用Reflection.Emit的匹配現有的構造

public class Program<T> 
{ 
    private List<T> _items; 

    public Program(T x, [Microsoft.Scripting.ParamDictionary] Microsoft.Scripting.IAttributesCollection col) 
    { 
     _items = new List<T>(); 
     _items.Add(x); 
    } 
} 

這裏是一個構造函數的IL:

.method public hidebysig specialname rtspecialname 
     instance void .ctor(!T x, 
          class [Microsoft.Scripting]Microsoft.Scripting.IAttributesCollection col) cil managed 
{ 
    .param [2] 
    .custom instance void [Microsoft.Scripting]Microsoft.Scripting.ParamDictionaryAttribute::.ctor() = (01 00 00 00) 
    // Code size  34 (0x22) 
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: call  instance void [mscorlib]System.Object::.ctor() 
    IL_0006: nop 
    IL_0007: nop 
    IL_0008: ldarg.0 
    IL_0009: newobj  instance void class [mscorlib]System.Collections.Generic.List`1<!T>::.ctor() 
    IL_000e: stfld  class [mscorlib]System.Collections.Generic.List`1<!0> class Foo.Program`1<!T>::_items 
    IL_0013: ldarg.0 
    IL_0014: ldfld  class [mscorlib]System.Collections.Generic.List`1<!0> class Foo.Program`1<!T>::_items 
    IL_0019: ldarg.1 
    IL_001a: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<!T>::Add(!0) 
    IL_001f: nop 
    IL_0020: nop 
    IL_0021: ret 
} // end of method Program`1::.ctor 

我想了解IL代碼通過散發它自己。這是我設法發出的:

.method public hidebysig specialname rtspecialname 
     instance void .ctor(!T A_1, 
          class [Microsoft.Scripting]Microsoft.Scripting.IAttributesCollection A_2) cil managed 
{ 
    // Code size  34 (0x22) 
    .maxstack 4 
    IL_0000: ldarg.0 
    IL_0001: call  instance void [mscorlib]System.Object::.ctor() 
    IL_0006: ldarg.0 
    IL_0007: newobj  instance void class [mscorlib]System.Collections.Generic.List`1<!T>::.ctor() 
    IL_000c: stfld  class [mscorlib]System.Collections.Generic.List`1<!0> class MyType<!T>::_items 
    IL_0011: ldarg.0 
    IL_0012: ldfld  class [mscorlib]System.Collections.Generic.List`1<!0> class MyType<!T>::_items 
    IL_0017: ldarg.s A_1 
    IL_0019: nop 
    IL_001a: nop 
    IL_001b: nop 
    IL_001c: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<!T>::Add(!0) 
    IL_0021: ret 
} // end of method MyType::.ctor 

有一些差異,我只是無法弄清楚。我真的很接近...

  1. 如何照顧參數屬性(ParamDictionaryAttribute)?我無法找到'自定義'操作碼。

  2. .param [2]是否重要?我如何發出這個?

  3. 爲什麼C#代碼堆棧大小爲8,而我的發射版本是4?這很重要嗎?

回答

3

.custom不是操作碼,它是應用自定義屬性的方式。它是聲明的一部分。它與.param緊密相連。 .param[2]告訴我們現在我們將談論第二個參數。 .custom應用指定的參數。看看MSIL spec,225頁,201和199(用於.maxstack)

要設置自定義構造函數上的參數調用DefineParameter屬性和您使用SetCustomAttribute()上構造函數將適用於它

1

- > 1./2。在構造函數構建器上使用DefineParameter()(而不是使用type[]定義它們),然後可以執行SetCustomAttribute()以將該屬性應用於參數。

- > 3.我認爲這並不重要。它基本上指定了該方法能夠運行的堆棧數量。

+0

得到ParameterBuilder通話SetCustomAttribute() attrib屬於ctor,但它適用於參數,請參閱我的答案。 – Andrey 2010-03-30 16:48:36

+0

對不起,沒有意識到。更新了我的答案(和你+1)。 – Lucero 2010-03-30 16:56:08

相關問題