Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to add only an attribute on a class at runtime?
    primarykey
    data
    text
    <p>I managed to create this class at run time with Reflection Emit:</p> <pre><code>[DelimitedRecord(",")] public partial 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; } } } </code></pre> <p>like this:</p> <pre><code> //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 Type[] delimiterAttributeParams = new Type[] { typeof(string) }; ConstructorInfo delimiterAttrInfo = typeof(DelimitedRecordAttribute).GetConstructor(delimiterAttributeParams); CustomAttributeBuilder delimiterAttributeBuilder = new CustomAttributeBuilder(delimiterAttrInfo, new object[] { ";" }); typeBuilder.SetCustomAttribute(delimiterAttributeBuilder); //create the firstName field FieldBuilder firstNameField = typeBuilder.DefineField("firstName", typeof(System.String), FieldAttributes.Private); //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); //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)] Type[] lastNameFieldOrderAttributeParams = new Type[] { typeof(int) }; ConstructorInfo lastNameFieldOrderAttrInfo = typeof(FieldOrderAttribute).GetConstructor(lastNameFieldOrderAttributeParams); CustomAttributeBuilder lastNameFieldOrderAttributeBuilder = new CustomAttributeBuilder(lastNameFieldOrderAttrInfo, new object[] { 1 }); lastNameField.SetCustomAttribute(lastNameFieldOrderAttributeBuilder); //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); </code></pre> <p>What i would really like is to declare my class like this:</p> <pre><code> public partial class Person { private string firstName; private string lastName; public string FirstName { get { return firstName; } set { firstName = value; } } public string LastName { get { return lastName; } set { lastName = value; } } } </code></pre> <p>and at run time only add those attributes. For the first name field i am thinking at something like this</p> <pre><code> //get the builder to that field FieldBuilder firstNameField = //create the 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); </code></pre> <p>How to get the builder to that field?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload