MSIL实用指南-生成索引器

索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item"和"set_Item"。

下面我们来生成如下的带有索引器的类

using System;

namespace LX1_ILDemo
{
public class IndexerDemo
{
private string[,] _CustomerNames; public string this[int, int]
{
get
{
return this._CustomerNames[num, num2];
}
set
{
this._CustomerNames[num, num2] = value;
}
}
}
}

第一步,生成一个字段
生成字段用TypeBuilder.DefineField方法。
实例代码:
FieldBuilder CustomerNamesBldr = typeBuilder.DefineField
("_CustomerNames",typeof(string[,]),FieldAttributes.Private);

第二步,创建一个名称为Item的PropertyBuilder对象
创建PropertyBuilder对象需要用生成字段用方法

PropertyBuilder custNamePropBldr = typeBuilder.DefineProperty
("Item", PropertyAttributes.HasDefault,typeof(string),new Type[] { typeof(int), typeof(int) });

注意定义这个PropertyBuilder对象是有参数new Type[] { typeof(int), typeof(int) }的。

第三步,生成get和set方法
方法名为"get_Item"和"set_Item"。

MethodAttributes getSetAttr =
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // 定义get方法
MethodBuilder custNameGetPropMthdBldr =
typeBuilder.DefineMethod("get_Item", getSetAttr, typeof(string) , new Type[] { typeof(int), typeof(int) }); ILGenerator ilGetGenerator = custNameGetPropMthdBldr.GetILGenerator();
LocalBuilder localBuilderv1 = ilGetGenerator.DeclareLocal(typeof(string));
ilGetGenerator.Emit(OpCodes.Ldarg_0);
ilGetGenerator.Emit(OpCodes.Ldfld, CustomerNamesBldr);
ilGetGenerator.Emit(OpCodes.Ldarg_1);
ilGetGenerator.Emit(OpCodes.Ldarg_2);
ilGetGenerator.Emit(OpCodes.Call ,typeof(string[,]).GetMethod("Get",new Type[] { typeof(int), typeof(int) }));
ilGetGenerator.Emit(OpCodes.Stloc_0);
ilGetGenerator.Emit(OpCodes.Ldloc_0);
ilGetGenerator.Emit(OpCodes.Ret); // 定义set方法
MethodBuilder custNameSetPropMthdBldr =
typeBuilder.DefineMethod("set_Item", getSetAttr, null, new Type[] { typeof(int), typeof(int), typeof(string) }); ILGenerator ilSetGenerator = custNameSetPropMthdBldr.GetILGenerator();
ilSetGenerator.Emit(OpCodes.Ldarg_0);
ilSetGenerator.Emit(OpCodes.Ldfld, CustomerNamesBldr);
ilSetGenerator.Emit(OpCodes.Ldarg_1);
ilSetGenerator.Emit(OpCodes.Ldarg_2);
ilSetGenerator.Emit(OpCodes.Ldarg_3);
ilSetGenerator.Emit(OpCodes.Call, typeof(string[,]).GetMethod("Set", new Type[] { typeof(int), typeof(int), typeof(string) }));
ilSetGenerator.Emit(OpCodes.Ret); custNamePropBldr.SetGetMethod(custNameGetPropMthdBldr);
custNamePropBldr.SetSetMethod(custNameSetPropMthdBldr);

第四步,给类加DefaultMemberAttribute特性
用反射查找DefaultMemberAttribute类型,传入参数值为"Item",创建一个DefaultMemberAttribute实例,
源码如下

Type myType = typeof(DefaultMemberAttribute);
ConstructorInfo infoConstructor = myType.GetConstructor(new Type[] { typeof(string) });
CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(infoConstructor, new object[] {"Item" });
typeBuilder.SetCustomAttribute(attributeBuilder);

完整程序如下:

using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
class Demo12_Indexer
{
static string binaryName = "Demo12_Indexer.dll";
static string namespaceName = "LX1_ILDemo";
static string typeName = "IndexerDemo"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder; private static void Generate_Indexer()
{
FieldBuilder CustomerNamesBldr = typeBuilder.DefineField
("_CustomerNames",typeof(string[,]),FieldAttributes.Private); PropertyBuilder custNamePropBldr = typeBuilder.DefineProperty
("Item", PropertyAttributes.HasDefault,typeof(string),new Type[] { typeof(int), typeof(int) }); MethodAttributes getSetAttr =
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // 定义get方法
MethodBuilder custNameGetPropMthdBldr =
typeBuilder.DefineMethod("get_Item", getSetAttr, typeof(string) , new Type[] { typeof(int), typeof(int) }); ILGenerator ilGetGenerator = custNameGetPropMthdBldr.GetILGenerator();
LocalBuilder localBuilderv1 = ilGetGenerator.DeclareLocal(typeof(string));
ilGetGenerator.Emit(OpCodes.Ldarg_0);
ilGetGenerator.Emit(OpCodes.Ldfld, CustomerNamesBldr);
ilGetGenerator.Emit(OpCodes.Ldarg_1);
ilGetGenerator.Emit(OpCodes.Ldarg_2);
ilGetGenerator.Emit(OpCodes.Call ,typeof(string[,]).GetMethod("Get",new Type[] { typeof(int), typeof(int) }));
ilGetGenerator.Emit(OpCodes.Stloc_0);
ilGetGenerator.Emit(OpCodes.Ldloc_0);
ilGetGenerator.Emit(OpCodes.Ret); // 定义set方法
MethodBuilder custNameSetPropMthdBldr =
typeBuilder.DefineMethod("set_Item", getSetAttr, null, new Type[] { typeof(int), typeof(int), typeof(string) }); ILGenerator ilSetGenerator = custNameSetPropMthdBldr.GetILGenerator();
ilSetGenerator.Emit(OpCodes.Ldarg_0);
ilSetGenerator.Emit(OpCodes.Ldfld, CustomerNamesBldr);
ilSetGenerator.Emit(OpCodes.Ldarg_1);
ilSetGenerator.Emit(OpCodes.Ldarg_2);
ilSetGenerator.Emit(OpCodes.Ldarg_3);
ilSetGenerator.Emit(OpCodes.Call, typeof(string[,]).GetMethod("Set", new Type[] { typeof(int), typeof(int), typeof(string) }));
ilSetGenerator.Emit(OpCodes.Ret); custNamePropBldr.SetGetMethod(custNameGetPropMthdBldr);
custNamePropBldr.SetSetMethod(custNameSetPropMthdBldr); SetTypeAttr();
} private static void SetTypeAttr()
{
Type myType = typeof(DefaultMemberAttribute);
ConstructorInfo infoConstructor = myType.GetConstructor(new Type[] { typeof(string) });
CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(infoConstructor, new object[] {"Item" });
typeBuilder.SetCustomAttribute(attributeBuilder);
} public static void Generate()
{
InitAssembly(); typeBuilder = moduleBuilder.DefineType( namespaceName+"."+ typeName, TypeAttributes.Public);
Generate_Indexer(); 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实用指南-生成属性

    本篇讲解怎么生成属性,包括get和set方法. 第一步,生成一个字段生成字段用TypeBuilder.DefineField方法.实例代码: FieldBuilder customerNameBldr ...

  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. caffe+CPU︱虚拟机+Ubuntu16.04+CPU+caffe安装笔记

    由于本机是window10系统,所以想尝试caffe就在自己电脑上整了一个虚拟机(详情可见:win10系统搭建虚拟机:VMware Workstation Player 12环境+Ubuntu Kyl ...

  2. 一句python,一句R︱python中的字符串操作、中文乱码

    先学了R,最近刚刚上手python,所以想着将python和R结合起来互相对比来更好理解python.最好就是一句python,对应写一句R. pandas可谓如雷贯耳,数据处理神器. 以下符号: = ...

  3. EDKII Build Process:EDKII项目源码的配置、编译流程[三]

    <EDKII Build Process:EDKII项目源码的配置.编译流程[3]>博文目录: 3. EDKII Build Process(EDKII项目源码的配置.编译流程) -> ...

  4. bootrom的构成

    bootrom的构成 在开发阶段,VxWorks 操作系统大多采用bootrom+ VxWorks 方式启动,即下载型方式进行.一方面,由于VxWorks本身调试的需要,另一方面,bootrom相比V ...

  5. 【mongodb系统学习之五】mongodb启动最常用参数

    五.mongodb启动时其他常用参数的使用(都是选用): 1).--logappend,指定日志的写入方式为追加,强烈建议使用: 2).--port,指定mongodb的端口号,当不使用这个参数的时候 ...

  6. 错误号码2003 Can't connect to MySQL server 'localhost' (0)

    错误描述 错误原因 最近,我一直都可以用SQLyog连接本地数据库,但是近几天却无法连接:并且一直都报上述错误,我查阅了很多资料,发现有很多中说法 总结一下 第一,MySQL中的my.ini出错: 第 ...

  7. Linux显示历史记录

    Linux显示历史记录 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ history 1 uname -a 2 lsusb 3 df -h 4 ps -A 5 ...

  8. Xshell配色为ubuntu风格

    背景 为了远程连接服务器,用Xshell作为连接工具,因为好(mian)用(fei),服务器是ubuntu的,因此看不习惯Xshell自带的黑白色,下面给出了ubuntu的配色方案,使用的时候直接导入 ...

  9. 浅析git

    git是什么 简单来说,Git,它是一个快速的 分布式版本控制系统 (Distributed Version Control System,简称 DVCS) . 同传统的 集中式版本控制系统 (Cen ...

  10. Gradle下载 Jar 包

    使用此方法下载Jar包的前提是已经配置好了Gradle的环境了,配置好的标志是在终端输入gradle不提示command not found. 1. 编写build.gradle文件代码: apply ...