Create a class dynamically with Reflection.Emit. I got stuck

.net, c#, reflection.emit

Solution

I made it work:

//create the Delimiter attribute
Type[] attributeParams = new Type[] { typeof(string) };
ConstructorInfo classCtorInfo = typeof(DelimitedRecordAttribute).GetConstructor(attributeParams);
CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(classCtorInfo, new object[] { ";" });
typeBuilder.SetCustomAttribute(attributeBuilder);

This would do the job for the field attributes:

//create the firstName attribute [FieldOrder(0)]
Type[] firstNameFieldOrderAttributeParams = new Type[] { typeof(int) };
ConstructorInfo firstNameFieldOrderAttrInfo = typeof(FieldOrderAttribute).GetConstructor(firstNameFieldOrderAttributeParams);
CustomAttributeBuilder firstNameFieldOrderAttributeBuilder = new CustomAttributeBuilder(firstNameFieldOrderAttrInfo, new object[] { 0 });
firstNameField.SetCustomAttribute(firstNameFieldOrderAttributeBuilder);

Problem

A read about creating types at runtime and i found it amazing. My goal is to create this class: ``` [DelimitedRecord(",")] public class Person { [FieldOrder(0)] private string firstName; [FieldOrder(1)] private string lastName; public string FirstName { get { return firstName; } set { firstName = value; } } public string LastName { get { return lastName; } set { lastName = value; } } } ``` I did this: ``` //create the builder AssemblyName assembly = new AssemblyName("FileHelpersTests"); AppDomain appDomain = System.Threading.Thread.GetDomain(); AssemblyBuilder assemblyBuilder = appDomain.DefineDynamicAssembly(assembly, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assembly.Name); //create the class TypeBuilder typeBuilder = moduleBuilder.DefineType("Person", TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit, typeof(System.Object)); //create the Delimiter attribute //create the firstName field FieldBuilder firstNameField = typeBuilder.DefineField("firstName", typeof(System.String), FieldAttributes.Private); //create the firstName attribute [FieldOrder(0)] //create the FirstName property PropertyBuilder firstNameProperty = typeBuilder.DefineProperty("FirstName", PropertyAttributes.HasDefault, typeof(System.String), null); //create the FirstName Getter MethodBuilder firstNamePropertyGetter = typeBuilder.DefineMethod("get_FirstName", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, typeof(System.String), Type.EmptyTypes); ILGenerator firstNamePropertyGetterIL = firstNamePropertyGetter.GetILGenerator(); firstNamePropertyGetterIL.Emit(OpCodes.Ldarg_0); firstNamePropertyGetterIL.Emit(OpCodes.Ldfld, firstNameField); firstNamePropertyGetterIL.Emit(OpCodes.Ret); //create the FirstName Setter MethodBuilder firstNamePropertySetter = typeBuilder.DefineMethod("set_FirstName", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new Type[] { typeof(System.String) }); ILGenerator firstNamePropertySetterIL = firstNamePropertySetter.GetILGenerator(); firstNamePropertySetterIL.Emit(OpCodes.Ldarg_0); firstNamePropertySetterIL.Emit(OpCodes.Ldarg_1); firstNamePropertySetterIL.Emit(OpCodes.Stfld, firstNameField); firstNamePropertySetterIL.Emit(OpCodes.Ret); //assign getter and setter firstNameProperty.SetGetMethod(firstNamePropertyGetter); firstNameProperty.SetSetMethod(firstNamePropertySetter); //create the lastName field FieldBuilder lastNameField = typeBuilder.DefineField("lastName", typeof(System.String), FieldAttributes.Private); //create the lastName attribute [FieldOrder(1)] //create the LastName property PropertyBuilder lastNameProperty = typeBuilder.DefineProperty("LastName", PropertyAttributes.HasDefault, typeof(System.String), null); //create the LastName Getter MethodBuilder lastNamePropertyGetter = typeBuilder.DefineMethod("get_LastName", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, typeof(System.String), Type.EmptyTypes); ILGenerator lastNamePropertyGetterIL = lastNamePropertyGetter.GetILGenerator(); lastNamePropertyGetterIL.Emit(OpCodes.Ldarg_0); lastNamePropertyGetterIL.Emit(OpCodes.Ldfld, lastNameField); lastNamePropertyGetterIL.Emit(OpCodes.Ret); //create the FirstName Setter MethodBuilder lastNamePropertySetter = typeBuilder.DefineMethod("set_FirstName", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new Type[] { typeof(System.String) }); ILGenerator lastNamePropertySetterIL = lastNamePropertySetter.GetILGenerator(); lastNamePropertySetterIL.Emit(OpCodes.Ldarg_0); lastNamePropertySetterIL.Emit(OpCodes.Ldarg_1); lastNamePropertySetterIL.Emit(OpCodes.Stfld, lastNameField); lastNamePropertySetterIL.Emit(OpCodes.Ret); //assign getter and setter lastNameProperty.SetGetMethod(lastNamePropertyGetter); lastNameProperty.SetSetMethod(lastNamePropertySetter); ``` I got stuck while creating those attributes: - The one at class level - The one at field level This is what ILDASM shows when i click The constructor ``` .class public auto ansi beforefieldinit FileHelpersTests.Person extends [mscorlib]System.Object { .custom instance void [FileHelpers]FileHelpers.DelimitedRecordAttribute::.ctor(string) = ( 01 00 01 2C 00 00 ) // ...,.. } // end of class FileHelpersTests.Person ``` The firstName field ``` .field private string firstName .custom instance void [FileHelpers]FileHelpers.FieldOrderAttribute::.ctor(int32) = ( 01 00 00 00 00 00 00 00 ) ```

Original source