Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Attribute not added correctly in Reflection.Emit assembly

In creating a dynamic assembly using Relection.Emit, I am trying to create a method and decorate it with the System.Runtime.CompilerServices.MethodImplAttribute. I successfully create and save the assembly with the method, but when I load the saved assembly, my method does not seem to have any custom attributes. Here is my code creating the assembly:

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");

After the above code runs, I grab the MyAssembly.dll file and reference it in a different project. When I run this code, it reports there are zero custom attributes on my method:

var attributes = typeof(MyAssembly.MyType).GetMethod("MyMethod").GetCustomAttributes(false);
// empty array!
like image 429
Mr Anderson Avatar asked Mar 11 '26 06:03

Mr Anderson


2 Answers

That's because some attributes aren't really attributes, but are actually IL primitives. This applies to [Serializable], and a few others - including (apparently) this one; here's the IL from "ildasm":

.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

Note the aggressiveinlining.

like image 157
Marc Gravell Avatar answered Mar 13 '26 18:03

Marc Gravell


This is special attribute and, as stated in its documentation:

The members of the MethodImplOptions enumeration correspond to bit fields in the CorMethodImpl metadata table. This means that information on the attribute cannot be retrieved at run time by calling the MemberInfo.GetCustomAttributes method; instead, it is retrieved by calling either the MethodInfo.GetMethodImplementationFlags or the ConstructorInfo.GetMethodImplementationFlags method.

So it is applied correctly, which you can verify by inspecting what documentation above says:

bool isAggressiveInlined = typeof(MyAssembly.MyType).GetMethod("MyMethod")
 .MethodImplementationFlags.HasFlag(MethodImplAttributes.AggressiveInlining);
like image 23
Evk Avatar answered Mar 13 '26 18:03

Evk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!