本篇讲解怎么生成和操作一维数组。各种数组类型创建的步骤是一样的,但是加载和保存步骤有所不同。

一.创建数组
所有类型的一维数组创建都是一样的,分三步。
1.加载数组长度
2.生成指令 Newarr <数组成员类型>
3.保存

实例代码:

ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(int));
ilGenerator.Emit(OpCodes.Stloc_0);

二.数组的成员保存
这里的数组类型是byte、short、int、long、float、double和其它。它们的保存到成员的步骤是相似的。
首先以int型为例,它有四步。
1.加载数组变量
2.加载索引号
3.加载值
4.生成Stelem_I4指令

实例程序:

ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldc_I4, int.MaxValue);
ilGenerator.Emit(OpCodes.Stelem_I4);

其它几种类型的前三步和int类型是一样的,只有最后一步不同,它们各有各的指令,对应关系是

byte:Stelem_I1
short:Stelem_I2
int:Stelem_I4
long:Stelem_I8
float:Stelem_R4
double:Stelem_R8
其它:Stelem_Ref

三.其它类型的成员加载
加载也和保存类似。首先以int型数组为例,要分三步
1.加载数组变量
2.加载索引号
3.生成Ldelem_I4指令
实例程序:

ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_I4);

  

其它类型的第三步指令各不相同,对应关系是
byte:Ldelem_I1
short:Ldelem_I2
int:Ldelem_I4
long:Ldelem_I8
float:Ldelem_R4
double:Ldelem_R8
其它:Ldelem_Ref

完整的程序如下

using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
public class Demo21_ArrayOne
{
static string binaryName = "Demo21_ArrayOne.dll";
static string namespaceName = "LX1_ILDemo";
static string typeName = "DemoArrayOne"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder;
static MethodBuilder methodBuilder;
static ILGenerator ilGenerator;
public static void Generate()
{
InitAssembly();
typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public | TypeAttributes.Abstract); methodBuilder = typeBuilder.DefineMethod("TestArray",
MethodAttributes.Public | MethodAttributes.Static,
typeof(void), new Type[] { });
ilGenerator = methodBuilder.GetILGenerator(); LocalBuilder localBuilderv1 = ilGenerator.DeclareLocal(typeof(int[]));
LocalBuilder localBuilderv2 = ilGenerator.DeclareLocal(typeof(int));
LocalBuilder localBuilderv3 = ilGenerator.DeclareLocal(typeof(float[]));
LocalBuilder localBuilderv4 = ilGenerator.DeclareLocal(typeof(float));
LocalBuilder localBuilderv5 = ilGenerator.DeclareLocal(typeof(string[]));
LocalBuilder localBuilderv6 = ilGenerator.DeclareLocal(typeof(string)); ilGenerator.Emit(OpCodes.Nop);
Generate_IntArray();
Generate_FloatArray();
Generate_StringArray(); ilGenerator.Emit(OpCodes.Ret);
SaveAssembly();
Console.WriteLine("生成成功");
} static void Generate_IntArray()
{
ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(int));
ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldc_I4, int.MaxValue);
ilGenerator.Emit(OpCodes.Stelem_I4); ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_I4);
ilGenerator.Emit(OpCodes.Stloc_1);
} static void Generate_FloatArray()
{
ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(float));
ilGenerator.Emit(OpCodes.Stloc_2); ilGenerator.Emit(OpCodes.Ldloc_2);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldc_I4, float.MaxValue);
ilGenerator.Emit(OpCodes.Stelem_R4); ilGenerator.Emit(OpCodes.Ldloc_2);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_R4);
ilGenerator.Emit(OpCodes.Stloc_3);
} static void Generate_StringArray()
{
ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(string));
ilGenerator.Emit(OpCodes.Stloc_S, (sbyte)); ilGenerator.Emit(OpCodes.Ldloc_S, (sbyte));
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldstr,"test string");
ilGenerator.Emit(OpCodes.Stelem_Ref); ilGenerator.Emit(OpCodes.Ldloc_S, (sbyte));
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_Ref);
ilGenerator.Emit(OpCodes.Stloc_S, (sbyte));
} 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实用指南-Action的生成和调用

    MSIL实用指南-Action的生成和调用 System.Action用于封装一个没有参数没有返回值的方法.这里生成需要Ldftn指令. 下面讲解怎生成如下的程序. class ActionTest ...

  3. MSIL实用指南-struct的生成和操作

    struct(结构)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体.所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例分配在线程的堆栈( ...

  4. MSIL实用指南-装箱拆箱

    本篇讲述怎样装箱拆箱.装箱和拆箱都是针对值类型而言的,装箱的性能开销远比拆箱的性能开销大. 装箱装箱指令是Box.使用格式是 ILGenerator.Emit(OpCodes.Box,<值类型& ...

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

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

  6. MSIL实用指南-给字段、属性、方法、类、程序集加Attribute

    C#编程中可以给字段.方法.类以及程序集加特性即继承于Attribute的类.这里讲解怎么在IL中给它们加上特性. 生成字段的对应的类是FieldBuilder,生成属性的对应的类是PropertyB ...

  7. MSIL实用指南-创建对象

    创建对象用Newobj指令,它的操作是创建一个新的对象或值类型,并将对象引用的新实例到计算堆栈上.格式是Newobj <构造函数>实例: ilGenerator.Emit(OpCodes. ...

  8. MSIL实用指南-IL版hello world

    我们学习编程开始时,一般用输出"hello world"的一段程序. C#版的"hello world"是 using System; namespace L0 ...

  9. MSIL实用指南-加载null、string、long、float、double等值

    本篇讲述怎么加载null.string值.long值.float值.double值. 加载null不需要参数值,只要 Emit ldnull 其它几个命令要 Emit <指令> <值 ...

随机推荐

  1. angular中$q.all用法

    $q.all是用于执行多个异步任务进行回调,它可以接受一个promise的数组,或是promise的hash(object).任何一个promise失败,都会导致整个任务的失败. 例1:接受一个pro ...

  2. Eclipse增强代码提示插件Code Recommenders安装,顺便说说Eclipse插件安装方法

    1.为什么用Code Recommenders 在用过Intelij Idea后,发现它的自动代码提示非常智能,可以敲关键字就能提示,但是因为公司用的是Eclipse, 所以想找有没有这个插件能增强代 ...

  3. SAPUI5 freestyle vs SAP Fiori Elements —— 两种开发SAP UI5 Apps的方式对比

    概述 目前SAPUI5 SDK 提供了两种方式来开发一个SAPUI5 App.一种方式是传统的SAPUI5开发方式,一种是利用SAP Fiori Elements通过模板快速构建应用的方式. 本文简单 ...

  4. TypeScript入门知识一(字符串特性)

    一,TypeScript多行字符串 传统JavaScript字符串换行需要+进行拼接,而TypeScript不需要+拼接.看下面实例: javaScript: var content = " ...

  5. web前端UI框架

    分类:WEB前端 时间:2016年1月13日 目前,众多互联网公司APP都嵌入了大量的HTML5,移动端的开发越来越重视,HTML5的运用场景也越来越多了.在移动WEB开发的过程中,使用合适的移动WE ...

  6. JavaIO 总结

    另外参考文章:http://www.ibm.com/developerworks/cn/java/j-lo-javaio/ 一. File类 file.createNewFile();file.del ...

  7. 自签名证书和私有CA签名的证书的区别 创建自签名证书 创建私有CA 证书类型 证书扩展名【转】

    自签名的证书无法被吊销,CA签名的证书可以被吊销 能不能吊销证书的区别在于,如果你的私钥被黑客获取,如果证书不能被吊销,则黑客可以伪装成你与用户进行通信   如果你的规划需要创建多个证书,那么使用私有 ...

  8. 纯代码实现wordpress文章隐藏内容评论可见

    在很多网站上都看过这个效果,比如说知己知彼网站,他的部分资源是需要我们评论后才能下载的,那么这个到底有什么用呢,对我而言,除了拿来装逼,还可以增加我的评论数量,不多说,先看看效果: 其实WordPre ...

  9. 【Unity与23种设计模式】原型模式(Prototype)

    GoF中定义: "使用原型对象来产生指定类的对象,所以产生对象时,是使用复制原型对象来完成." Unity中 开发者可以组装游戏对象 它可以包括复杂的组件 组装好了之后,就可以将其 ...

  10. 第一迭代目标——future weather

    第一个迭代目标(主要数据) 引导界面.获取天气数据(api接口).天气分享 人员工作分配: 引导界面:周子静,界面的引导,耗时3天 获取天气数据:包舒婷.俞先浩,api接口,耗时5天 天气分享:郭磊蕾 ...