惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
I
InfoQ
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
Y
Y Combinator Blog
博客园_首页
Martin Fowler
Martin Fowler
宝玉的分享
宝玉的分享
A
About on SuperTechFans
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss
C
Check Point Blog
B
Blog RSS Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Engineering at Meta
Engineering at Meta
B
Blog
爱范儿
爱范儿
Stack Overflow Blog
Stack Overflow Blog
aimingoo的专栏
aimingoo的专栏
WordPress大学
WordPress大学
F
Fortinet All Blogs
月光博客
月光博客
GbyAI
GbyAI

博客园 - 蓝狐

Java Been, EJB, POJO 之间的区别 Tomcat启动报错Invalid character found in method name. HTTP method names must be tokens Eclipse中Tomcat Server启动后马上又自动停止报错Address已经使用8005端口 Can't assign requested address (Bind failed) Eclipse中Tomcat的配置及简单例子 jsp页面都放在web-inf下面说是要防止用户直接访问jsp页面,为么不能直接访问jsp CATS patch on 20130513 SharePoint 2010 根据不同的用户权限显示不同的导航 (原创)Sharepoint webpart中调用web service报错 vs2010 调试dll文件的方法 sharepoint 2010 打开网站导航管理页面,实现多级菜单 sharepoint 2010中备份和还原的方法 SharePoint2010多级导航配置(转) C# SerialPort System.ObjectDisposedException, safe handle has been closed 解决方案 说说大型高并发高负载网站的系统架构 (转) 大型网站的架构设计问题----大型高并发高负载网站的系统架构(转) sql 行专列 列转行 普通行列转换 ajaxpro总是运行时语法错误--如何进行JS脚本调试 手动生成WebService代理类的简单办法 (摘) - 蓝狐 - 博客园 由WSDL文件生成WEB service server端C#程序 (摘)
动态创建类型及属性--转 - 蓝狐 - 博客园
蓝狐 · 2011-01-14 · via 博客园 - 蓝狐

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

    }

}