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

一.创建数组
所有类型的一维数组创建都是一样的,分三步。
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. 从FCN到DeepLab

    图像语义分割,简单而言就是给定一张图片,对图片上的每一个像素点分类. 图像语义分割,从FCN把深度学习引入这个任务,一个通用的框架事:前端使用FCN全卷积网络输出粗糙的label map,后端使用CR ...

  2. javascript使用闭包模拟私有属性和方法

    最近因为做了一个项目,其中涉及到了js私有方法,这个概念在其语言里面是很常见的,很多语言都有private这个关键字,只要在一个类的前面加上private就表示申明了一个私有方法,但是javascri ...

  3. 浅析git

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

  4. vsto下开发wps插件

    我们要开发wps插件了.之前用vsto开发过word插件,我也讲过c#下如何开发wps插件(有点繁琐).如果采用c#从头再开发wps插件,那么开发出来的office加载项就会出现两个.我们要实现的wp ...

  5. MinGW安装和使用

    P.S.安装MinGW主要是code blocks 编译出现了这个问题: ERROR: You need to specify a debugger program in the debuggers' ...

  6. 怎么用secureCRT连接Linux

    首先要安装linux,参看:http://www.cnblogs.com/shenjieblog/p/5061282.html 然后要安装secureCRT,参看:http://www.cnblogs ...

  7. MSIL实用指南-创建字段

    本篇讲解怎么创建字段,主要是在修饰符的创建上. 创建字段的方法是TypeBuilder.DefineField,传入字段名称.字段类型.字段修饰符等参数,返回一个FieldBuilder对象.先看这一 ...

  8. python函数式编程之生成器

    在前面的学习过程中,我们知道,迭代器有两个好处: 一是不依赖索引的统一的迭代方法 二是惰性计算,节省内存 但是迭代器也有自己的显著的缺点,那就是 不如按照索引取值方便 一次性,只能向后取值,不能向前取 ...

  9. 关于脱离laravel框架使用Illuminate/Validation验证器

    1.关于Illuminate/Validation验证器 Validation 类用于验证数据以及获取错误消息. github地址:github.com/illuminate/validation 文 ...

  10. 1.使用dom4j解析XML文件

    一.dom4j的简介 dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的.dom4j是一个十分优秀的JavaXML API,具有性能优异.功能强大和极其易使用的特点,它 ...