代码之家  ›  专栏  ›  技术社区  ›  Mr Anderson

反射中未正确添加自定义属性。发射部件

  •  2
  • Mr Anderson  · 技术社区  · 8 年前

    在使用创建动态部件时 Relection.Emit ,我试图创建一种方法并用 System.Runtime.CompilerServices.MethodImplAttribute 。我使用该方法成功地创建并保存了程序集,但当我加载保存的程序集时,我的方法似乎没有任何自定义属性。下面是我创建程序集的代码:

    ConstructorInfo methodImplCtor = typeof(System.Runtime.CompilerServices.MethodImplAttribute).GetConstructor(new[] { typeof(System.Runtime.CompilerServices.MethodImplOptions) });
    // stores the constructor I wish to use
    
    AssemblyBuilder assm = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("MyAssembly"), AssemblyBuilderAccess.Save);
    ModuleBuilder module = assm.DefineDynamicModule("MyAssembly", "MyAssembly.dll", false);
    TypeBuilder type = module.DefineType("MyAssembly.MyType", TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed);
    MethodBuilder method = type.DefineMethod("MyMethod", MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, typeof(int), new[] { typeof(int) });
    
    method.SetCustomAttribute(new CustomAttributeBuilder(methodImplCtor, new object[] { System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining }));
    
    ILGenerator il = method.GetILGenerator();
    il.Emit(OpCodes.Ldarg_0);
    il.Emit(OpCodes.Ret);
    
    type.CreateType();
    assm.Save("MyAssembly.dll");
    

    在上述代码运行之后,我获取MyAssembly。dll文件,并在其他项目中引用它。当我运行此代码时,它报告我的方法上没有自定义属性:

    var attributes = typeof(MyAssembly.MyType).GetMethod("MyMethod").GetCustomAttributes(false);
    // empty array!
    
    2 回复  |  直到 8 年前
        1
  •  1
  •   Marc Gravell    8 年前

    那是因为一些属性 不是真正的属性 ,但实际上是IL基元。这适用于 [Serializable] ,还有其他一些——包括(显然)这一个;以下是“ildasm”的IL:

    .method public hidebysig static int32  MyMethod(int32 A_0) cil managed aggressiveinlining
    {
      // Code size       2 (0x2)
      .maxstack  1
      IL_0000:  ldarg.0
      IL_0001:  ret
    } // end of method MyType::MyMethod
    

    请注意 aggressiveinlining

        2
  •  1
  •   Evk    8 年前

    这是一个特殊属性,如 documentation :

    MethodImplOptions枚举的成员对应于位 CorMethodImpl元数据表中的字段。这意味着 无法在运行时检索有关属性的信息 正在调用MemberInfo。GetCustomAttributes方法 ;相反,它是 通过调用 MethodInfo。GetMethodImplementationFlags或 ConstructorInfo。GetMethodImplementationFlags方法。

    因此,它是正确应用的,您可以通过检查上面的文档来验证:

    bool isAggressiveInlined = typeof(MyAssembly.MyType).GetMethod("MyMethod")
     .MethodImplementationFlags.HasFlag(MethodImplAttributes.AggressiveInlining);