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!
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With