MSIL实用指南-生成属性
本篇讲解怎么生成属性,包括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实用指南-生成属性的更多相关文章
- MSIL实用指南-生成索引器
MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...
- MSIL实用指南-生成构造函数
本篇讲解生成构造函数的一些知识,包括创建实例构造函数.静态构造函数.调用父类构造函数. 生成构造函数的方法生成构造函数的方法是TypeBuilder.DefineConstructor(MethodA ...
- MSIL实用指南-生成接口
本篇讲解怎么样生成接口,即interface. 一.创建类型创建一个接口类型依旧用ModuleBuilder的DefineType方法,但是它的第二个参数必须要有TypeAttributes.Inte ...
- MSIL实用指南-生成if...else...语句
if...else...语句是非常重要的选择语句,它的生成一般需要ILGenerator的DefineLabel方法和MarkLabel方法,以及Brtrue_S和Br_S指令. 一.DefineLa ...
- MSIL实用指南-生成内部类
生成内部类用TypeBuilder的DefineNestedType方法,得到另一个TypeBuilder.内部类的可访问性都是TypeAttributes的“Nested”开头一些成员.实例代码:y ...
- MSIL实用指南-生成foreach语句
foreach可以迭代数组或者一个集合对象.foreach语句格式是它的生成步骤是foreach (<成员> in <集合>) <循环体> 一.声明三个变量,loc ...
- MSIL实用指南-生成for语句
for语句格式是这样的for(<初始化语句>;<条件语句>;<自增减语句>) <循环体> 它可以转换为while语句 if(<条件语句>){ ...
- MSIL实用指南-生成异常处理
本篇讲解怎么生成异常.C# 异常处理时建立在四个关键词之上的:try.catch.finally 和 throw. 一.异常的抛出抛出异常在C#语言中要使用throw关键字,使用方法是throw &l ...
- MSIL实用指南-生成while语句
本篇讲解怎样生成while语句.while语句是编程语言中很重要的循环语句,它的结构是while(<表达式>) <语句或语句块> 当表达式的结果为true时就一直执行语句或语句 ...
随机推荐
- 使用基于Android网络通信的OkHttp库实现Get和Post方式简单操作服务器JSON格式数据
目录 前言 1 Get方式和Post方式接口说明 2 OkHttp库简单介绍及环境配置 3 具体实现 前言 本文具体实现思路和大部分代码参考自<第一行代码>第2版,作者:郭霖:但是文中讲 ...
- 1000多个项目中的十大JavaScript错误以及如何避免
通过统计数据库中的1000多个项目,我们发现在 JavaScript 中最常出现的错误有10个.下面会向大家介绍这些错误发生的原因以及如何防止. 对于这些错误发生的次数,我们是通过收集的数据统计得出的 ...
- ‘true’==true返回false详解
JavaScript高级程序设计(第3版) 第三章非常完整地解释了原因. 3.5.7 相等操作符 在转换不同的数据类型时,相等和不相等操作符遵循下列基本规则: . 如果有一个操作数是布尔值,则在比较 ...
- arm-linux-gcc: Command not found 问题解析 .
问题: sudo tar jxvf cross-2.95.3.tar.bz2 export PATH=$PATH:/usr/local/arm/2.95.3/bin 使用arm-linux-gcc – ...
- Android 插件化方案(动态加载)总结
1.作用 大多数Android开发人员开始接触这个问题是因为 App 爆棚了,方法数超过了一个 Dex 最大方法数 65535 的上限,因而便有了插件化的概念,将一个 App 划分为多个插件(Apk ...
- Action调用Service
Java Web项目,写到Action的时候,往往会要引入Service,这个是一个常见的操作. 但是,我自认为引入Service需要给它get和set方法,并且这个习惯已经沿用到现在.然而,自从参与 ...
- Android app security安全问题总结
数据泄漏 本地文件敏感数据不能明文保存,不能伪加密(Base64,自定义算法等) android:allowbackup=false. 防止 adb backup 导出数据 Activity inte ...
- PHPmysqli的 其他函数 从数据库中读出数据并且打印出来
<?php // 认识其他mysqli其他函数 header( 'Content-Type:text/html;charset=utf-8 '); require 'prepareSrarmen ...
- MP4文件格式的解析
MP4文件格式的解析,以及MP4文件的分割算法 mp4应该算是一种比较复杂的媒体格式了,起源于QuickTime.以前研究的时候就花了一番的功夫,尤其是如何把它完美的融入到视频点播应用中,更是费尽了心 ...
- javax.el.PropertyNotFoundException:Property 'statisDate' not found on type java.lang.String
1.错误描述 javax.el.PropertyNotFoundException:Property 'statisDate' not found on type java.lang.String 2 ...