How can I generate virtual properties using AssemblyBuilder in C # 4.0?

I am currently working on creating an assembly with virtual properties. Examples in MSDN only create normal properties. How to create a class inside an assembly with virtual properties?

I would like to create 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; }
    }

There is no PropertyAttributes.Virtual in the PropertyBuilder class, so I do not know how to create a virtual property. If I create this class myself in Visual Studio, and then open it in Reflector , the properties will be virtual, so this is possible.

How can I do that?

+3
source share
1 answer

, 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);
    }
}

, , virtual PropertyBuilder, , . , , , getter setter. MethodAttributes .

+3

Source: https://habr.com/ru/post/1732826/


All Articles