4

首先,这里是 C# 代码和反汇编的 IL:

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?这很重要吗?

4

2 回答 2

3

.custom不是操作码,它是应用自定义属性的方式。它是声明的一部分。它与 紧密结合.param.param[2]告诉我们现在我们将讨论第二个参数。.custom应用指定的参数。查看MSIL 规范,第 225 页、第 201 和第 199 页(适用于 .maxstack)

DefineParameter在 ctor上的参数调用上设置自定义属性,然后ParameterBuilder调用 SetCustomAttribute()

于 2010-03-30T16:47:55.170 回答
1

-> 1./2。DefineParameter()在构造函数生成器上使用(而不是用 定义它们type[]),然后您可以执行 aSetCustomAttribute()将属性应用于参数。

-> 3. 我认为这并不重要。它基本上指定了该方法必须有多少可用的堆栈才能运行。

于 2010-03-30T16:38:41.157 回答