如何使用 C# 4.0 中的 AssemblyBuilder 生成虚拟属性?

发布于 2024-08-21 08:19:13 字数 712 浏览 7 评论 0原文

我目前正在努力创建具有虚拟属性的程序集。 MSDN 上的示例仅创建普通属性。如何在具有虚拟属性的程序集中创建一个类?

我希望能够生成这样的类:

    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 中打开它,属性它们本身是虚拟的,所以这是可能的。

怎么办呢?

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 virtual, so it is possible.

How can it be done?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沉鱼一梦 2024-08-28 08:19:13

以下是在运行时创建一个类的示例,该类包含一个虚拟的整数属性 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 枚举。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文