.net - 使用 Reflection.Emit 匹配现有的构造函数

标签 .net cil reflection.emit

首先,这里是 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

有一些差异,我只是想不通。我真的很接近...
  • 如何处理参数属性 (ParamDictionaryAttribute)?我找不到“自定义”操作码。
  • .param [2] 重要吗?我怎么发出那个?
  • 为什么 C# 代码堆栈大小是 8,而我发出的版本是 4?这很重要吗?
  • 最佳答案

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

    在参数调用上设置自定义属性 DefineParameter在 ctor 上你会得到 ParameterBuilder调用 SetCustomAttribute()在上面

    关于.net - 使用 Reflection.Emit 匹配现有的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2546840/

    相关文章:

    .net - TextChanged 事件 - 为什么这不会导致无限循环?

    .net - 调用和 Callvirt

    c# - 如何正确发出和使用类?

    c# - Reflection.Emit 泛型基类泛型方法调用

    c# - 升级 .NET 版本后,TwoWay 或 OneWayToSource 绑定(bind)无法对只读属性起作用

    .net - vs 编译器提示 project.json 中缺少引用,但 .net proj 不是核心

    c# - 我如何(正确地)通过 .NET 使用 RSA 和 SHA256 验证文件?

    c# - IL 和参数

    .net - 关于 CorDbg 和 Mdbg 的良好资源

    c# - 解决类型是否支持接口(interface)的最佳方法? (鸭子类型(duck typing))