• 动态创建类型及属性转


    using System;

    using System.Reflection;

    using System.Reflection.Emit;

    /// <summary>

    /// 用于创建动态类型,并添加各个 public 属性的定义

    /// </summary>

    public class DynamicTypeBuilder

    {

        TypeBuilder tb;

        /// <summary>

        /// 构造函数

        /// </summary>

        /// <param name="typeNm">动态类型的名称</param>

        public DynamicTypeBuilder(string typeNm)

        {

            // 在 Silverlight 中 AssemblyBuilderAccess 没有 RunAndSave

            AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(

                new AssemblyName("TempAssembly"), AssemblyBuilderAccess.Run);

            ModuleBuilder mb = ab.DefineDynamicModule("TempModule");

            this.tb = mb.DefineType(typeNm, TypeAttributes.Public);

        }

        /// <summary>

        /// 添加一个public的可读写属性,并且会创建对应的名为 propertyNm + "Field" 的私有字段

        /// </summary>

        /// <param name="propertyNm"></param>

        /// <param name="type"></param>

        public void AppendPublicProperty(string propertyNm, Type type)

        {

            this.AppendPublicProperty(propertyNm, type, true, true);

        }

        /// <summary>

        /// 添加一个public属性,并且会创建对应的名为 propertyNm + "Field" 的私有字段

        /// </summary>

        /// <param name="propertyNm"></param>

        /// <param name="type"></param>

        /// <param name="canGet">是否实现getter</param>

        /// <param name="canSet">是否实现setter</param>

        public void AppendPublicProperty(string propertyNm, Type type, bool canGet, bool canSet)

        {

            FieldBuilder field = this.tb.DefineField(string.Format("{0}Field", propertyNm), type, FieldAttributes.Private);

            PropertyBuilder property = tb.DefineProperty(propertyNm, PropertyAttributes.HasDefault, type, null);

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

            if (canGet)

            {

                MethodBuilder getAccessor = tb.DefineMethod(string.Format("get_{0}", propertyNm), getSetAttr, type, Type.EmptyTypes);

                ILGenerator getIL = getAccessor.GetILGenerator();

                #region 按照 IL 代码的写法

                // 按照 IL 代码的写法,不能运行

                //.method public hidebysig specialname instance int32

                //        get_A() cil managed

                //{

                //  // Code size       12 (0xc)

                //  .maxstack  1

                //  .locals init ([0] int32 CS$1$0000)

                //  IL_0000:  nop

                //  IL_0001:  ldarg.0

                //  IL_0002:  ldfld      int32 WpfApplication2.Person::AField

                //  IL_0007:  stloc.0

                //  IL_0008:  br.s       IL_000a

                //  IL_000a:  ldloc.0

                //  IL_000b:  ret

                //} // end of method Person::get_A

                // 按照上面 IL 代码的写法,不能运行 :

                //Label getBrsLabel = getIL.DefineLabel();

                //getIL.Emit(OpCodes.Nop);

                //getIL.Emit(OpCodes.Ldarg_0);

                //getIL.Emit(OpCodes.Ldfld, field);

                //getIL.Emit(OpCodes.Stloc_0);

                //getIL.Emit(OpCodes.Br_S, getBrsLabel);

                //getIL.MarkLabel(getBrsLabel);

                //getIL.Emit(OpCodes.Ldloc_0);

                //getIL.Emit(OpCodes.Ret);

                #endregion

                // For an instance property, argument default is the instance. Load the

                // instance, then load the private field and return, leaving the

                // field value on the stack.

                getIL.Emit(OpCodes.Ldarg_0);

                getIL.Emit(OpCodes.Ldfld, field);

                getIL.Emit(OpCodes.Ret);

                property.SetGetMethod(getAccessor);

            }

            if (canSet)

            {

                MethodBuilder setAccessor = tb.DefineMethod(string.Format("set_{0}", propertyNm), getSetAttr, null, new Type[] { type });

                setAccessor.DefineParameter(1, ParameterAttributes.None, "value");

                ILGenerator setIL = setAccessor.GetILGenerator();

                // Load the instance and then the numeric argument, then store the

                // argument in the field.

                setIL.Emit(OpCodes.Ldarg_0);

                setIL.Emit(OpCodes.Ldarg_1);

                setIL.Emit(OpCodes.Stfld, field);

                setIL.Emit(OpCodes.Ret);

                property.SetSetMethod(setAccessor);

            }

        }

        /// <summary>

        /// 在添加完各个 public 属性之后,调用此方法以完成对动态类型的定义并加载之,

        /// 此后通过 Activator.CreateInstance() 便可实例化动态类型

        /// </summary>

        /// <returns></returns>

        public Type CreateDynamicType()

        {

            return this.tb.CreateType();

        }

    }

  • 相关阅读:
    Django之cookie与session
    Django之在Python中调用Django环境
    Django之Django终端打印SQL语句
    Django之事务
    Django之ORM操作(聚合 分组、F Q)
    Linux常用服务安装部署
    Linux服务基础命令
    程序员的vim
    Linux的xshell命令
    Linux操作服务器的初识
  • 原文地址:https://www.cnblogs.com/newwind521/p/1935259.html
Copyright © 2020-2023  润新知