2016-02-23 5 views
1

после внедрения, которая создает класс и свойство динамически:Добавить атрибут к свойству динамически

public static class MyTypeBuilder 
{ 
    public static void CreateNewObject() 
    { 
     var myType = CompileResultType(); 

    } 
    public static Type CompileResultType() 
    { 
     TypeBuilder tb = GetTypeBuilder(); 
     ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); 

         var fields = new List<Field>() { 
      new Field("EmployeeID", typeof(int)), 
      new Field("EmployeeName", typeof(string)), 
      new Field("Designation", typeof(string)) 
     }; 

     // NOTE: assuming your list contains Field objects with fields FieldName(string) and FieldType(Type) 
         foreach (var field in fields) 
      CreateProperty(tb, field.FieldName, field.FieldType); 

     Type objectType = tb.CreateType(); 
     return objectType; 
    } 

    private static TypeBuilder GetTypeBuilder() 
    { 
     var typeSignature = "MyDynamicType"; 
     var an = new AssemblyName(typeSignature); 
     AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); 
     ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); 
     TypeBuilder tb = moduleBuilder.DefineType(typeSignature 
          , TypeAttributes.Public | 
          TypeAttributes.Class | 
          TypeAttributes.AutoClass | 
          TypeAttributes.AnsiClass | 
          TypeAttributes.BeforeFieldInit | 
          TypeAttributes.AutoLayout 
          , null); 
     return tb; 
    } 

    private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType) 
    { 
     FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); 

     PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); 
     MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes); 
     ILGenerator getIl = getPropMthdBldr.GetILGenerator(); 

     getIl.Emit(OpCodes.Ldarg_0); 
     getIl.Emit(OpCodes.Ldfld, fieldBuilder); 
     getIl.Emit(OpCodes.Ret); 

     MethodBuilder setPropMthdBldr = 
      tb.DefineMethod("set_" + propertyName, 
       MethodAttributes.Public | 
       MethodAttributes.SpecialName | 
       MethodAttributes.HideBySig, 
       null, new[] { propertyType }); 

     ILGenerator setIl = setPropMthdBldr.GetILGenerator(); 
     Label modifyProperty = setIl.DefineLabel(); 
     Label exitSet = setIl.DefineLabel(); 

     setIl.MarkLabel(modifyProperty); 
     setIl.Emit(OpCodes.Ldarg_0); 
     setIl.Emit(OpCodes.Ldarg_1); 
     setIl.Emit(OpCodes.Stfld, fieldBuilder); 

     setIl.Emit(OpCodes.Nop); 
     setIl.MarkLabel(exitSet); 
     setIl.Emit(OpCodes.Ret); 

     propertyBuilder.SetGetMethod(getPropMthdBldr); 
     propertyBuilder.SetSetMethod(setPropMthdBldr); 
    } 
} 

В то же над реализацией я хочу добавить атрибут для свойства Пример

[DelimitedRecord(",")] 
    [IgnoreEmptyLines()] 
    private class myDyanmicType 
    { 
     [FieldQuoted('"', QuoteMode.OptionalForBoth)] 
     public int EmployeeID;  
     [FieldQuoted('"', QuoteMode.OptionalForBoth)] 
     public String EmployeeName; 
     [FieldQuoted('"', QuoteMode.OptionalForBoth)] 
     public String Designation;   

    } 

так я хочу добавить атрибут свойства, такого как

[FieldQuoted('"', QuoteMode.OptionalForBoth)]

как я добьюсь этого с моим кодом создания динамического класса и свойства

Пожалуйста, помогите.

+1

Нет, вы не можете этого сделать, если класс не был предназначен для этого. * Почему ты пытаешься это сделать? Можете ли вы использовать другой класс, который относится к экземпляру существующего класса? Трудно помочь вам без лишнего контекста. –

+0

, если нет, возможно динамически создать весь класс с динамическим свойством и атрибутом для свойства. теперь я могу динамически создавать класс и свойство с приведенным выше кодом, обновляя основное описание вопроса, пожалуйста, проверьте. – Liquid

+1

Да, вы можете создавать классы динамически или использовать ExpandoObject ... но это очень * отличается от слова «У меня уже есть класс, и я хочу динамически добавлять свойства». Пока неясно, чего вы пытаетесь достичь, или почему вы думаете, что лучше всего сделать это. –

ответ

0

Просто более простой и быстрый подход: напишите свой ценный код строке, затем скомпилируйте ее во время выполнения, и вы получите все готово!

string src = "[DelimitedRecord(\",\")] [IgnoreEmptyLines()] private class ..."; 
var compParms = new CompilerParameters 
      { 
       GenerateExecutable = false, 
       GenerateInMemory = true 
      }; 
var csProvider = new CSharpCodeProvider(); 
CompilerResults compilerResults = csProvider.CompileAssemblyFromSource(compParms, src); 
var a = compilerResults.CompiledAssembly; // here you go 
Смежные вопросы