• 动态创建类型及属性转


    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();

        }

    }

  • 相关阅读:
    bzoj2733 永无乡 平衡树按秩合并
    bzoj2752 高速公路 线段树
    bzoj1052 覆盖问题 二分答案 dfs
    bzoj1584 打扫卫生 dp
    bzoj1854 游戏 二分图
    bzoj3316 JC loves Mkk 二分答案 单调队列
    bzoj3643 Phi的反函数 数学 搜索
    有一种恐怖,叫大爆搜
    BZOJ3566 概率充电器 概率dp
    一些奇奇怪怪的过题思路
  • 原文地址:https://www.cnblogs.com/newwind521/p/1935259.html
Copyright © 2020-2023  润新知