MSIL实用指南-创建对象
创建对象用Newobj指令,它的操作是创建一个新的对象或值类型,并将对象引用的新实例到计算堆栈上。
格式是
Newobj <构造函数>
实例:
ilGenerator.Emit(OpCodes.Newobj, typeof(Uri).GetConstructor(new Type[] { typeof(string)}));
在调用Newobj指令前,需要加载构造函数所需要的参数。
完整程序如下:
using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
class Demo15_NewObj
{
static string binaryName = "Demo15_NewObj.exe";
static string namespaceName = "LX1_ILDemo";
static string typeName = "NewObjDemo"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder;
static MethodBuilder mainMethod;
static ILGenerator ilGenerator; static void Emit_ILCode()
{
LocalBuilder localBuilderv1 = ilGenerator.DeclareLocal(typeof(Uri));
ilGenerator.Emit(OpCodes.Ldstr, "http://www.contoso.com/");
ilGenerator.Emit(OpCodes.Newobj, typeof(Uri).GetConstructor(new Type[] { typeof(string)}));
ilGenerator.Emit(OpCodes.Stloc_0);
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }));
} public static void Generate()
{
InitAssembly(); typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public); GenerateMain(); Emit_ILCode(); EmitReadKey();
ilGenerator.Emit(OpCodes.Ret); /* 设置assembly入口方法 */
assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication); SaveAssembly();
Console.WriteLine("生成成功");
} static void EmitReadKey()
{
/* 生成 Console.ReadKey(); */
MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { });
ilGenerator.Emit(OpCodes.Call, readKeyMethod);
ilGenerator.Emit(OpCodes.Pop);
} static void GenerateMain()
{
mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public
| MethodAttributes.Static, typeof(void), new Type[] { });
ilGenerator = mainMethod.GetILGenerator();
} 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实用指南-Action的生成和调用
MSIL实用指南-Action的生成和调用 System.Action用于封装一个没有参数没有返回值的方法.这里生成需要Ldftn指令. 下面讲解怎生成如下的程序. class ActionTest ...
- MSIL实用指南-IL版hello world
我们学习编程开始时,一般用输出"hello world"的一段程序. C#版的"hello world"是 using System; namespace L0 ...
- MSIL实用指南-加载null、string、long、float、double等值
本篇讲述怎么加载null.string值.long值.float值.double值. 加载null不需要参数值,只要 Emit ldnull 其它几个命令要 Emit <指令> <值 ...
- MSIL实用指南-加载bool、sbyte、byte、char、short等值
这一篇讲解怎么加载bool值.sbyte值.byte值.char值.short值. 加载bool值在.NET程序实际运行中,是没有true和false值的,实际上是以1和0表示它们,加载它们的指令是L ...
- MSIL实用指南-局部变量的声明、保存和加载
这一篇讲解方法内的局部变量是怎么声明.怎样保存.怎样加载的. 声明局部变量声明用ILGenerator的DeclareLocal方法,参数是局部变量的数据类型,得到一个局部变量对应的创建类LocalB ...
- MSIL实用指南-创建字段
本篇讲解怎么创建字段,主要是在修饰符的创建上. 创建字段的方法是TypeBuilder.DefineField,传入字段名称.字段类型.字段修饰符等参数,返回一个FieldBuilder对象.先看这一 ...
- MSIL实用指南-创建枚举类型
创建枚举类型比较简单,主要使用moduleBuilder.DefineEnum 和enumBuilder.DefineLiteral. 第一步:创建 EnumBuilder 创建 EnumBuilde ...
- MSIL实用指南-创建方法和定义参数
本篇讲解实现创建方法.指定参数的名称.实现参数加out和ref修饰符.以及参数加默认值. 创建方法 创建方法用类TypeAttributes的 DefineMethod(string name, Me ...
随机推荐
- C# ORM简单原理
对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去. 在今日的企业环境中,把面向对象 ...
- markdown常用方法
Markdown格式的普及流行要归功于Github和StackOverflow的流行,随着它们越来越流行,它们支持的Markdown格式也越来越流行. 1.优点 1.Markdown通过内容和样式相分 ...
- poj 1068 模拟
题目链接 大概题意就是告诉你有个n个小括号,每一个")"左边有多少个"("都告诉你了,然后让你求出每一对括号之间有多少对括号(包含自己本身). 思路: 我先计算 ...
- powershell小脚本--批量添加用户属性----导出登录时间
需求1:某公司所有员工少了MAIL属性,需要批量添加.例如,用户chenyy 添加邮件属性chenyy@xxxx.com 先导出(只导出名字)备用: Get-ADUser -Filter * -Pr ...
- React 基于antd+video.js实现m3u8格式视频播放及实时切换
文档连接地址(官网看起麻烦,看中文别人整理好的)https://blog.csdn.net/a0405221/article/details/80923090 React项目使用 安装依赖 npm ...
- kali,ubuntu, debain DNS 配置
kali 是基于 debain 的一个 Linux 发行版 DNS 的配置 是在文件 /etc/resolv.conf 下. 但是,我们会发现 /etc/resolv.conf 每次重启都会失效, ...
- SpringBoot 集成Jedis操作set
题外话: Redis是个有趣的东西,相信搞java的或多或少都会用到,面试时也总离不开问Redis,之前觉得redis只是用做缓存,飞快!也因为最初在封装底层的时候,使用Redisson,所以大部分都 ...
- 【Aizu - 2249】Road Construction(最短路 Dijkstra算法)
Road Construction Descriptions Mercer国王是ACM王国的王者.他的王国里有一个首都和一些城市.令人惊讶的是,现在王国没有道路.最近,他计划在首都和城市之间修建道路, ...
- html5 placeholder属性兼容ie11
placeholder 属性是html5的属性,用于提供描述输入字段预期值的提示信息(hint). 简单例子: <!DOCTYPE HTML> <html> <body& ...
- js中toFixed精度问题的解决办法
toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.例如将数据Num保留2位小数,则表示为:toFixed(Num):但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规 ...