How can I generate Virtual Properties with the AssemblyBuilder in C# 4.0?
I'm currently working on creating an Assembly with virtual properties. The examples on MSDN are only creating normal properties. How do I create a class inside an assembly which has virtual properties?
I would like to be able to generate a class like this:
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; }
}
The PropertyBuilder class doesn't have PropertyAttributes.Virtual, so I don't know how to create a virtual property. If I create this class in Visual Studio myself, and then open it in Reflector, the properties themselfes are vi开发者_JAVA百科rtual, so it is possible.
How can it be done?
Here's an example of creating a class at runtime that contains a single integer property Id
which is virtual:
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);
}
}
The reason you don't find anything related to virtual
in the PropertyBuilder
is because properties don't have this concept. Methods can be virtual, so when you declare a virtual property you are declaring virtual getter and setter methods. Take a look at MethodAttributes enumeration.
精彩评论