本篇讲解实现创建方法、指定参数的名称、实现参数加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实用指南-创建方法和定义参数的更多相关文章

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

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

  2. MSIL实用指南-创建枚举类型

    创建枚举类型比较简单,主要使用moduleBuilder.DefineEnum 和enumBuilder.DefineLiteral. 第一步:创建 EnumBuilder 创建 EnumBuilde ...

  3. MSIL实用指南-加载和保存参数

    本篇讲解怎么加载和保存参数,以及参数起始序号的确定. 参数的加载加载参数的指令是Ldarg.Ldarg_S.Ldarg_0.Ldarg_1.Ldarg_2.Ldarg_3.Ldarg_0是加载第0个参 ...

  4. MSIL实用指南-生成索引器

    MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...

  5. MSIL实用指南-Action的生成和调用

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

  6. MSIL实用指南-生成属性

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

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

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

  8. MSIL实用指南-方法的调用

    方法调用指令主要有Call和Callvirt. 调用static或sealed修饰的方法,用Call指令. 调用virtual或abstract修饰的方法,用Callvirt指令. 代码实例: ilG ...

  9. MSIL实用指南-闭包的生成和调用

    闭包(Closure)是词法闭包(Lexical Closure)的简称.对闭包的具体定义有很多种说法,这些说法大体可以分为两类: 一种说法认为闭包是符合一定条件的函数,比如参考资源中这样定义闭包:闭 ...

随机推荐

  1. Java数字签名——RSA算法

    数字签名:带有密钥(公钥,私钥)的消息摘要算法. 验证数据的完整性,认证数据的来源,抗否性 OSI参考模型 私钥签名,公钥验证 签名算法:RSA,DSA,ECDSA 算法1 :RSA MD,SHA两类 ...

  2. 《android开发艺术探索》读书笔记(四)--View工作原理

    接上篇<android开发艺术探索>读书笔记(三) No1: View的三大流程:测量流程.布局流程.绘制流程 No2: ViewRoot对应于ViewRootImpl类,它是连接Wind ...

  3. Codeforces475D - CGCDSSQ

    Portal Description 给出长度为\(n(n\leq10^5)\)的序列\(\{a_n\}\),给出\(q(q\leq3\times10^5)\)个\(x\),对于每个\(x\),求满足 ...

  4. Linux 的进程状态

    (1)运行:当一个进程在处理机上运行时,则称该进程处于运行状态.处于此状态的进程的数目小于等于处理器的数目,对于单处理机系统,处于运行状态的进程只有一个.在没有其他进程可以执行时(如所有进程都在阻塞状 ...

  5. 嵌入式 RTP通话:视频流(H.264)的传输

    从摄像头获取的视频数据,经过编码后(当然,也可以不编码,如果你觉得也很ok的话),既可以 是  开始的数据是  00 00 40 00 40 11 C1 8C 94字节) 四.RTP视频传输代码 #d ...

  6. freemarker处理空值

    freemarker处理空值 1.设计思路 (1)封装学生类和课程类 (2)新建学生课程页面ftl文件 (3)创建测试方法 2.封装课程类 Course.java: /** * @Title:Cour ...

  7. linux下mount/unmount命令

    格式:mount [-参数] [设备名称] [挂载点] 其中常用的参数有:-a 安装在/etc/fstab文件中类出的所有文件系统.-f 伪装mount,作出检查设备和目录的样子,但并不真正挂载文件系 ...

  8. directX根据设备类GUID查询所属的filter

    hr = m_pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0);    ASSERT(SUCCEEDED(hr));    ...

  9. Exynos4412交叉编译环境搭建

    Exynos4412交叉编译环境搭建 交叉编译:在PC机(x86平台)上开发程序,在ARM板上运行,提高开发.编译速度. 环境: Tiny4412SDK1506开发板 需要软件: arm-linux- ...

  10. C#读取Excel表格中数据并返回datatable

    在软件开发的过程中,经常用到从excel表格中读取数据作为数据源,以下整理了一个有效的读取excel表格的方法. DataTable GetDataTable(string tableName,str ...