2010-02-15 55 views
3

我目前正在創建一個具有虛擬屬性的程序集。 MSDN上的示例僅創建常規屬性。如何在具有虛擬屬性的程序集中創建類?如何使用C#4.0中的AssemblyBuilder生成虛擬屬性?

我希望能夠產生這樣的類:

public class ClassA 
    { 
     public virtual int Id { get; set; } 
     public virtual string Name { get; set; } 
     public virtual string ClassName { get; set; } 
     public virtual ClassB Partner { get; set; } 
    } 

    public class ClassB 
    { 
     public virtual int Id { get; set; } 
     public virtual string Name { get; set; } 
    } 

的PropertyBuilder類沒有PropertyAttributes.Virtual,所以我不知道如何創建一個虛擬財產。如果我自己在Visual Studio中創建這個類,然後在Reflector中打開它,則屬性本身是虛擬的,所以這是可能的。

怎麼辦?

回答

3

這裏是一個包含一個整數屬性Id這是虛擬的,在運行時創建類的實例:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var aName = new AssemblyName("DynamicAssemblyExample"); 
     var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run); 
     var mb = ab.DefineDynamicModule(aName.Name); 
     var tb = mb.DefineType("MyDynamicType", TypeAttributes.Public); 
     var fbId = tb.DefineField("_id", typeof(int), FieldAttributes.Private); 
     var pbId = tb.DefineProperty("Id", PropertyAttributes.HasDefault, typeof(int), null); 

     var getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual; 

     var mbIdGetAccessor = tb.DefineMethod("get_Id", getSetAttr, typeof(int), Type.EmptyTypes); 

     var numberGetIL = mbIdGetAccessor.GetILGenerator(); 
     numberGetIL.Emit(OpCodes.Ldarg_0); 
     numberGetIL.Emit(OpCodes.Ldfld, fbId); 
     numberGetIL.Emit(OpCodes.Ret); 

     var mbIdSetAccessor = tb.DefineMethod("set_Id", getSetAttr, null, new Type[] { typeof(int) }); 

     var numberSetIL = mbIdSetAccessor.GetILGenerator(); 
     numberSetIL.Emit(OpCodes.Ldarg_0); 
     numberSetIL.Emit(OpCodes.Ldarg_1); 
     numberSetIL.Emit(OpCodes.Stfld, fbId); 
     numberSetIL.Emit(OpCodes.Ret); 

     pbId.SetGetMethod(mbIdGetAccessor); 
     pbId.SetSetMethod(mbIdSetAccessor); 

     var t = tb.CreateType(); 
     var instance = Activator.CreateInstance(t); 
     Console.WriteLine(t.GetProperty("Id").GetGetMethod().IsVirtual); 
    } 
} 

你不覺得在PropertyBuilder有關virtual事情的原因是因爲性別沒有這個概念。方法可以是虛擬的,所以當你聲明一個虛擬屬性時,你聲明瞭虛擬的getter和setter方法。看看MethodAttributes枚舉。

+0

ab.Save()不保存您創建大會 (即使設置爲RunAndSave的AssemblyBuilderAccess) 你可以嘗試保存和加載組件裝回內存? 我在我自己的軟件中使用這個功能來解決.NET框架中的一個錯誤,該錯誤即使在保存之後也將該程序集定義爲運行時程序集。但是,如果我在你的代碼中使用它,它不會保存任何屬性或方法。 –

+0

Apperently我做了錯誤的代碼,它阻止了它的工作。重試後,它工作正常! –

+0

@ThijsCramer如果您將一個文件名傳遞給DefineDynamicModule方法,則稍後在使用ab.Save(FileName)時將保存該文件。我不知道它是一個錯誤還是一個功能,因爲你需要在兩個地方指定文件名,兩者都可以不同。程序集dll將引用模塊dll –

相關問題