开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜