本篇讲解怎么生成属性,包括get和set方法。

第一步,生成一个字段
生成字段用TypeBuilder.DefineField方法。
实例代码:

FieldBuilder customerNameBldr = typeBuilder.DefineField
("_CustomerName",typeof(string),FieldAttributes.Private);

第二步,创建一个PropertyBuilder对象
创建PropertyBuilder对象需要用生成字段用方法
TypeBuilder.DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes)。
返回的是一个PropertyBuilder对象。
参数说明:
name: 属性的名称。name 不能包含嵌入的 null 值。
attributes: 属性的特性。
returnType: 属性的返回类型。
parameterTypes:属性的参数类型。

实例代码:

PropertyBuilder custNamePropBldr = typeBuilder.DefineProperty
("CustomerName", PropertyAttributes.HasDefault,typeof(string),null);

第三步,生成get和set方法
get和set方法的特性需要是 MethodAttributes.SpecialName | MethodAttributes.HideBySig ,
实例代码:

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

get方法需要无参,返回类型与相关字段类型相同。
set方法需要一个参数,并且参数类型与相关字段的类型相同,无返回值。
实例代码:

MethodBuilder custNameGetPropMthdBldr =
typeBuilder.DefineMethod("get_CustomerName", getSetAttr,typeof(string),Type.EmptyTypes);
MethodBuilder custNameSetPropMthdBldr =
typeBuilder.DefineMethod("set_CustomerName",getSetAttr,null,new Type[] { typeof(string) });

第四步:实现get和set的方法体
这里直接给一个实例
实例代码:

ILGenerator custNameGetIL = custNameGetPropMthdBldr.GetILGenerator();
custNameGetIL.Emit(OpCodes.Ldarg_0);
custNameGetIL.Emit(OpCodes.Ldfld, customerNameBldr);
custNameGetIL.Emit(OpCodes.Ret); ILGenerator custNameSetIL = custNameSetPropMthdBldr.GetILGenerator();
custNameSetIL.Emit(OpCodes.Ldarg_0);
custNameSetIL.Emit(OpCodes.Ldarg_1);
custNameSetIL.Emit(OpCodes.Stfld, customerNameBldr);
custNameSetIL.Emit(OpCodes.Ret);

第五步,把get和set方法关联到PropertyBuilder对象上
管理get和set方法分别用PropertyBuilder对象的SetGetMethod和SetSetMethod方法
实例代码:

custNamePropBldr.SetGetMethod(custNameGetPropMthdBldr);
custNamePropBldr.SetSetMethod(custNameSetPropMthdBldr);

如果要生成一个只能get的属性,那么只要生成一个get方法,只调用SetGetMethod设置。
同理要生成一个只能set的属性,那么只要生成一个set方法,只调用SetSetMethod设置。

完整程序如下:

using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
class Demo11_Property
{
static string binaryName = "Demo11_Property.dll";
static string namespaceName = "LX1_ILDemo";
static string typeName = "PropertyDemo"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder; private static void Generate_Property1()
{
FieldBuilder customerNameBldr = typeBuilder.DefineField
("_CustomerName",typeof(string),FieldAttributes.Private); PropertyBuilder custNamePropBldr = typeBuilder.DefineProperty
("CustomerName", PropertyAttributes.HasDefault,typeof(string),null); MethodAttributes getSetAttr =
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // 定义get方法
MethodBuilder custNameGetPropMthdBldr =
typeBuilder.DefineMethod("get_CustomerName", getSetAttr,typeof(string),Type.EmptyTypes); ILGenerator custNameGetIL = custNameGetPropMthdBldr.GetILGenerator();
custNameGetIL.Emit(OpCodes.Ldarg_0);
custNameGetIL.Emit(OpCodes.Ldfld, customerNameBldr);
custNameGetIL.Emit(OpCodes.Ret); // 定义set方法
MethodBuilder custNameSetPropMthdBldr =
typeBuilder.DefineMethod("set_CustomerName",getSetAttr,null,new Type[] { typeof(string) }); ILGenerator custNameSetIL = custNameSetPropMthdBldr.GetILGenerator();
custNameSetIL.Emit(OpCodes.Ldarg_0);
custNameSetIL.Emit(OpCodes.Ldarg_1);
custNameSetIL.Emit(OpCodes.Stfld, customerNameBldr);
custNameSetIL.Emit(OpCodes.Ret); custNamePropBldr.SetGetMethod(custNameGetPropMthdBldr);
custNamePropBldr.SetSetMethod(custNameSetPropMthdBldr);
} private static void Generate_Property2()
{
FieldBuilder orgNameBldr = typeBuilder.DefineField
("_OrgName", typeof(string), FieldAttributes.Private); PropertyBuilder orgPropBldr = typeBuilder.DefineProperty
("OrgName", PropertyAttributes.HasDefault, typeof(string), null); MethodAttributes getSetAttr =
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; MethodBuilder custNameGetPropMthdBldr =
typeBuilder.DefineMethod("get_OrgName", getSetAttr, typeof(string), Type.EmptyTypes); ILGenerator custNameGetIL = custNameGetPropMthdBldr.GetILGenerator(); custNameGetIL.Emit(OpCodes.Ldarg_0);
custNameGetIL.Emit(OpCodes.Ldfld, orgNameBldr);
custNameGetIL.Emit(OpCodes.Ret);
orgPropBldr.SetGetMethod(custNameGetPropMthdBldr);
} public static void Generate()
{
InitAssembly(); typeBuilder = moduleBuilder.DefineType( namespaceName+"."+ typeName, TypeAttributes.Public); Generate_Property1();
Generate_Property2(); SaveAssembly();
Console.WriteLine("生成成功");
} static void InitAssembly()
{
AssemblyName assemblyName = new AssemblyName(namespaceName);
assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, binaryName);
} static void SaveAssembly()
{
Type t = typeBuilder.CreateType(); //完成Type,这是必须的
assemblyBuilder.Save(binaryName);
}
}
}

MSIL实用指南-生成属性的更多相关文章

  1. MSIL实用指南-生成索引器

    MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...

  2. MSIL实用指南-生成构造函数

    本篇讲解生成构造函数的一些知识,包括创建实例构造函数.静态构造函数.调用父类构造函数. 生成构造函数的方法生成构造函数的方法是TypeBuilder.DefineConstructor(MethodA ...

  3. MSIL实用指南-生成接口

    本篇讲解怎么样生成接口,即interface. 一.创建类型创建一个接口类型依旧用ModuleBuilder的DefineType方法,但是它的第二个参数必须要有TypeAttributes.Inte ...

  4. MSIL实用指南-生成if...else...语句

    if...else...语句是非常重要的选择语句,它的生成一般需要ILGenerator的DefineLabel方法和MarkLabel方法,以及Brtrue_S和Br_S指令. 一.DefineLa ...

  5. MSIL实用指南-生成内部类

    生成内部类用TypeBuilder的DefineNestedType方法,得到另一个TypeBuilder.内部类的可访问性都是TypeAttributes的“Nested”开头一些成员.实例代码:y ...

  6. MSIL实用指南-生成foreach语句

    foreach可以迭代数组或者一个集合对象.foreach语句格式是它的生成步骤是foreach (<成员> in <集合>) <循环体> 一.声明三个变量,loc ...

  7. MSIL实用指南-生成for语句

    for语句格式是这样的for(<初始化语句>;<条件语句>;<自增减语句>) <循环体> 它可以转换为while语句 if(<条件语句>){ ...

  8. MSIL实用指南-生成异常处理

    本篇讲解怎么生成异常.C# 异常处理时建立在四个关键词之上的:try.catch.finally 和 throw. 一.异常的抛出抛出异常在C#语言中要使用throw关键字,使用方法是throw &l ...

  9. MSIL实用指南-生成while语句

    本篇讲解怎样生成while语句.while语句是编程语言中很重要的循环语句,它的结构是while(<表达式>) <语句或语句块> 当表达式的结果为true时就一直执行语句或语句 ...

随机推荐

  1. 基于Python的Flask的开发实战(第一节Flask安装)

    1.安装python虚拟环境 easy_install virtualenv easy_install pip cd /home/admin virtualenv flask-website sour ...

  2. Linux文本的处理

    Linux最最最最重要的哲学思想就是:一切皆文件.文件以及文件的操作在LInux操作系统中是非常的重要.熟练使用精悍小巧快捷的文本处理方式让效率更高. 一.文件查看命令 less 分页查看 [root ...

  3. shell脚本基础 循环机构

    循环结构 for循环格式一格式:for 变量 in 值1 值2 ........(值不一定是数字,可以是命令或者其他的)do 命令done [root@ceshiji ~]# vim a.sh #!/ ...

  4. 网络基础Cisco路由交换四

    NAT及静态转换 概述(NAT:网络地址转化) 作用: 通过将内部网络的私有ip地址翻译成全球唯一的公网ip地址, 使内部网络可以连接到互联网等外部网络上. NATA的特性 优点: 节省公有合法ip地 ...

  5. windowsXP下搭建JAVA环境教程

    一.工具准备安装JKD6:传送门:http://www.java.net/download/jdk6/6u10/promoted/b32/binaries/jdk-6u10-rc2-bin-b32-w ...

  6. 利用ffmpeg做视频解码的顺序

    这几天在实验室捣鼓着用ffmpeg做视频解码,终于把数据解出来了,虽然还没有做显示部分,不知道解码解得对不对,但料想是不会有什么问题了.回头看看这几天的工作,其间也遇到了不少问题,主要还是对ffmpe ...

  7. mysql常用基础操作语法(二)~~对表的增删改操作【命令行模式】

    1.修改表名:alert table oldtablename rename newtablename; 或者alert table oldtablename rename to newtablena ...

  8. 航空客户价值分析特色LRFMC模型——RFM升级

    本文转载自微信公众号TIpDM. 每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 我们说RFM ...

  9. R语言︱list用法、批量读取、写出数据时的用法

    列表是一种特别的对象集合,它的元素也由序号(下标)区分,但是各元素的类型可 以是任意对象,不同元素不必是同一类型.元素本身允许是其它复杂数据类型,比如,列表 的一个元素也允许是列表.例如: > ...

  10. Linux查看用于终止进程命令

    Linux查看用于终止进程命令 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ ps PID TTY TIME CMD 2576 pts/0 00:00:00 ...