MSIL实用指南-创建方法和定义参数
本篇讲解实现创建方法、指定参数的名称、实现参数加out和ref修饰符、以及参数加默认值。
创建方法
创建方法用类TypeAttributes的
DefineMethod(string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes)
方法,返回结果是MethodBuilder,就可以创普通方法。
例子
MethodBuilder m2 = typeBuilder.DefineMethod("M2",
MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
typeof(string), new Type[] { typeof(int), typeof(string), typeof(object) });
这个写法就和下面的C#程序一样
public abstract void M1();
定义一个抽象方法需要用MethodAttributes的Abstract|Virtual才可以。
定义参数
用MethodBuilder的DefineParameter(int position, ParameterAttributes attributes, string strParamName)
方法
参数说明
position:该参数在参数列表中的位置。为参数编索引,第一个参数从数字 1 开始;数字 0 表示方法的返回值。
attributes: 参数的参数属性。
strParamName: 参数名。名称可以为 null 字符串。
返回结果:
返回一个 ParameterBuilder 对象,该对象表示此方法的参数或此方法的返回值。
1.指定参数的名称
在程序的方法调用中传入第三个参数传入参数名称就可以了。
例如
MethodBuilder m2 = typeBuilder.DefineMethod("M2",
MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
typeof(string), new Type[] { typeof(int), typeof(string), typeof(object) });
m2.DefineParameter(, ParameterAttributes.None, "arg0");
m2.DefineParameter(, ParameterAttributes.None, "param1");
m2.DefineParameter(, ParameterAttributes.None, "param2");
这个方法的三个参数名称依次是arg0、param1、param2。
2.指定参数out
我们要实现如下方法,参数的修饰符是out
public abstract string mout(out int arg3 );
需要使用ParameterAttributes.Out就可以了。
具体实现
MethodBuilder m5 = typeBuilder.DefineMethod("mout",
MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
typeof(string), new Type[] { typeof(int), typeof(int) });
ParameterBuilder m5p1 = m5.DefineParameter(1, ParameterAttributes.Out, "arg3");
3.实现参数默认值
要实现参数有默认值,比如下面这句
public abstract string mdefault(int arg1 = );
实现这个效果的程序是
MethodBuilder m3 = typeBuilder.DefineMethod("mdefault",
MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
typeof(string), new Type[] { typeof(int) });
ParameterBuilder m3p1 = m3.DefineParameter(, ParameterAttributes.HasDefault | ParameterAttributes.Optional, "arg1");
m3p1.SetConstant();
实现定义参数属性为ParameterAttributes.HasDefault | ParameterAttributes.Optional,并得到一个
ParameterBuilder实例,再设置这个实例的默认值。
4.实现指定参数ref
我们要实现如下方法,参数的修饰符是out
public abstract string mref(ref dobule arg2);
首先
MethodBuilder m4 = typeBuilder.DefineMethod("mref",
MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
typeof(string), new Type[] { Type.GetType("System.Double&") });
参数的类型不是一般的typeof(double),而要用特殊的Type.GetType("System.Double&")
其次
ParameterBuilder m4p1 = m4.DefineParameter(, ParameterAttributes.Out, "arg2");
要设置参数的属性为ParameterAttributes.Out
完整程序如下
using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
class Demo07_Method
{
static string binaryName = "Demo07_Method.dll";
static string namespaceName = "LX1_ILDemo";
static string typeName = "EmitMethod"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder; public static void Generate()
{
InitAssembly(); typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName,
TypeAttributes.Public | TypeAttributes.Abstract); /* 生成 public static void Main() */
GenerateMethods(); SaveAssembly();
Console.WriteLine("生成成功");
} static void GenerateMethods()
{
/* public abstract void M1(); */
MethodBuilder m1 = typeBuilder.DefineMethod("M1",
MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
typeof(void), new Type[] { }); /* public abstract string M2(int arg0,string param1); */
MethodBuilder m2 = typeBuilder.DefineMethod("M2",
MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
typeof(string), new Type[] { typeof(int), typeof(string), typeof(object) }); m2.DefineParameter(, ParameterAttributes.None, "arg0");
m2.DefineParameter(, ParameterAttributes.None, "param1");
m2.DefineParameter(, ParameterAttributes.None, "param2"); /* public abstract string mdefault(int arg1 =4 ); */
MethodBuilder m3 = typeBuilder.DefineMethod("mdefault",
MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
typeof(string), new Type[] { typeof(int) }); ParameterBuilder m3p1 = m3.DefineParameter(, ParameterAttributes.HasDefault | ParameterAttributes.Optional, "arg1");
m3p1.SetConstant(); /* public abstract string mref(ref dobule arg2); */
MethodBuilder m4 = typeBuilder.DefineMethod("mref",
MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
typeof(string), new Type[] { Type.GetType("System.Double&") }); ParameterBuilder m4p1 = m4.DefineParameter(, ParameterAttributes.Out, "arg2"); /* public abstract string mout(out int arg3 ); */
MethodBuilder m5 = typeBuilder.DefineMethod("mout",
MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
typeof(string), new Type[] { typeof(int), typeof(int) }); ParameterBuilder m5p1 = m5.DefineParameter(, ParameterAttributes.Out, "arg3");
} 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实用指南-创建字段
本篇讲解怎么创建字段,主要是在修饰符的创建上. 创建字段的方法是TypeBuilder.DefineField,传入字段名称.字段类型.字段修饰符等参数,返回一个FieldBuilder对象.先看这一 ...
- MSIL实用指南-创建枚举类型
创建枚举类型比较简单,主要使用moduleBuilder.DefineEnum 和enumBuilder.DefineLiteral. 第一步:创建 EnumBuilder 创建 EnumBuilde ...
- MSIL实用指南-加载和保存参数
本篇讲解怎么加载和保存参数,以及参数起始序号的确定. 参数的加载加载参数的指令是Ldarg.Ldarg_S.Ldarg_0.Ldarg_1.Ldarg_2.Ldarg_3.Ldarg_0是加载第0个参 ...
- MSIL实用指南-生成索引器
MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...
- MSIL实用指南-Action的生成和调用
MSIL实用指南-Action的生成和调用 System.Action用于封装一个没有参数没有返回值的方法.这里生成需要Ldftn指令. 下面讲解怎生成如下的程序. class ActionTest ...
- MSIL实用指南-生成属性
本篇讲解怎么生成属性,包括get和set方法. 第一步,生成一个字段生成字段用TypeBuilder.DefineField方法.实例代码: FieldBuilder customerNameBldr ...
- MSIL实用指南-给字段、属性、方法、类、程序集加Attribute
C#编程中可以给字段.方法.类以及程序集加特性即继承于Attribute的类.这里讲解怎么在IL中给它们加上特性. 生成字段的对应的类是FieldBuilder,生成属性的对应的类是PropertyB ...
- MSIL实用指南-方法的调用
方法调用指令主要有Call和Callvirt. 调用static或sealed修饰的方法,用Call指令. 调用virtual或abstract修饰的方法,用Callvirt指令. 代码实例: ilG ...
- MSIL实用指南-闭包的生成和调用
闭包(Closure)是词法闭包(Lexical Closure)的简称.对闭包的具体定义有很多种说法,这些说法大体可以分为两类: 一种说法认为闭包是符合一定条件的函数,比如参考资源中这样定义闭包:闭 ...
随机推荐
- FFmepg 如何在 window 上使用?
下载FFmepg官网库直接使用即可. avdevice.lib avcodec.lib avfilter.lib avformat.lib avutil.lib postproc.lib swresa ...
- struts2框架概述
框架概述 什么是框架,为什么使用框架,框架优点 框架(framework)是一个基本概念上的结构,用于去解决或者处理复杂的问题 框架,即framework.其实就是某种应用的半成品,就是一组组件,供你 ...
- 排序算法java实现
1. 插入排序 原理:遍历到第N个元素的时候前面的N-1个元素已经是排序好的了,那么就查找前面的N-1个元素把这第N个元素放在合适的位置,如此下去直到遍历完序列的元素为止. 算法的复杂度也是简单 ...
- WireShark过滤解析HTTP/TCP
过滤器的使用: 可利用“&&”(表示“与”)和“||”(表示“或”)来组合使用多个限制规则, 比如“(http && ip.dst == 64.233.189.104) ...
- Linux(二)命令
Linux命令一.命令基本格式 命令行头部显示字符意义 [root@localhost ~] # root 用户名 localhost 主机名 ~ 当前目录 ~表示home目录 # 用户权限,#表示超 ...
- vue之render基本书写方法
Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更接 ...
- NLP︱高级词向量表达(一)——GloVe(理论、相关测评结果、R&python实现、相关应用)
有很多改进版的word2vec,但是目前还是word2vec最流行,但是Glove也有很多在提及,笔者在自己实验的时候,发现Glove也还是有很多优点以及可以深入研究对比的地方的,所以对其进行了一定的 ...
- 3.3.3 PCI设备对可Cache的存储器空间进行DMA读写
PCI设备向"可Cache的存储器空间"进行读操作的过程相对简单.对于x86处理器或者PowerPC处理器,如果访问的数据在Cache中命中,CPU会通知FSB总线,PCI设备所访 ...
- MySQL通过localhost无法连接数据库的解决
问题:一台服务器的PHP程序通过localhost地址无法连接数据库,但是如果设置为127.0.0.1则可以正常连接,连接其他数据库服务器也正常.MySQL的权限设置正确,且通过mysql命令行客户端 ...
- WIN7 嵌入式系统安装教程 Windows Embedded Standard 2011 安装
轻松构建你的第一个 Windows Embedded Standard 2011 镜像.通过本文你可以快速掌握如何使用Windows Embedded Standard 2011 CTP1 来构建一个 ...