2016-02-23 136 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