IL接口和类的属性
上一篇文章学习了IL的入门,接下来我们再通过两个例子来了解下类的属性、构造函数以及接口的使用
一、类的属性、构造函数
1、先看下我们要构建的类的C#代码,然后再进行IL的实现,示例代码如下:
[Serializable]
public class Dynamic
{
;
public const string ConstField = "const";
/// <summary>
/// 定义属性
/// </summary>
public int A { get; set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="num"></param>
public Dynamic(int num)
{
this.A = num;
}
public int Add(int num)
{
return this.A + num;
}
}
2、通过以上代码我们可以根据要求先定义字段_a、常量ConstField(在构造函数过程中未使用到,帮组了解类属性的创建)以及给类加上序列化标签,属性可以通过TypeBuilder的DefineField创建,而序列化标签需要通过TypeBuilder的CustomAttributeBuilder去创建,示例代码如下:
//定义类可序列化
CustomAttributeBuilder serializable = new CustomAttributeBuilder(typeof(SerializableAttribute).GetConstructor(Type.EmptyTypes), new Type[] { });
typeBuilder.SetCustomAttribute(serializable);
//定义常量
FieldBuilder fieldConst = typeBuilder.DefineField("ConstField", typeof(string), FieldAttributes.Static | FieldAttributes.Public | FieldAttributes.Literal);
fieldConst.SetConstant("const");
//定义字段_a
FieldBuilder aField = typeBuilder.DefineField("_a", typeof(int), FieldAttributes.Private);
aField.SetConstant();
3、通过TypeBuilder的DefineProperty定义属性A,通过CustomAttributeBuilder给属性添加对应的标签,示例代码如下:
//定义属性A
PropertyBuilder propertyABuilder = typeBuilder.DefineProperty("A", PropertyAttributes.None, typeof(int), null);
CustomAttributeBuilder desAttributeBuilder = new CustomAttributeBuilder(typeof(DescriptionAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "属性A" });
propertyABuilder.SetCustomAttribute(desAttributeBuilder);//字段描述
4、定义A属性的get方法和set方法,get和set方法和普通的方法创建相同,用TypeBuilder的DefineMethod创建。示例代码如下:
//定义属性get方法
MethodBuilder methodABuilder = typeBuilder.DefineMethod("get", MethodAttributes.Public, typeof(Int32), Type.EmptyTypes);
ILGenerator GetIL = methodABuilder.GetILGenerator();
GetIL.Emit(OpCodes.Ldarg_0);
GetIL.Emit(OpCodes.Ldfld, aField);
GetIL.Emit(OpCodes.Ret);
propertyABuilder.SetGetMethod(methodABuilder);
//定义属性set方法
MethodBuilder methodBBuilder = typeBuilder.DefineMethod("set", MethodAttributes.Public, typeof(Int32), new Type[] { typeof(Int32) });
ILGenerator SetIL = methodBBuilder.GetILGenerator();
SetIL.Emit(OpCodes.Ldarg_0);
SetIL.Emit(OpCodes.Ldarg_1);
SetIL.Emit(OpCodes.Stfld, aField);
SetIL.Emit(OpCodes.Ret);
propertyABuilder.SetSetMethod(methodBBuilder);
5、构造函数的创建,构造函数是通过TypeBuilder的DefineConstructor去获取,构造函数包含一个参数并赋值给_a,示例代码如下:
//定义构造函数
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[] { typeof(Int32) });
ILGenerator constructorIL = constructorBuilder.GetILGenerator();
constructorIL.Emit(OpCodes.Ldarg_0);
constructorIL.Emit(OpCodes.Ldarg_1);
constructorIL.Emit(OpCodes.Stfld, aField);
constructorIL.Emit(OpCodes.Ret);
6、最后是定义方法。
//定义方法
MethodBuilder methodAddBuild = typeBuilder.DefineMethod("Add", MethodAttributes.Public, typeof(Int32), new Type[] { typeof(int) });
ILGenerator addIL = methodAddBuild.GetILGenerator();
addIL.Emit(OpCodes.Ldarg_0);
addIL.Emit(OpCodes.Ldfld, aField);
addIL.Emit(OpCodes.Ldarg_1);
addIL.Emit(OpCodes.Add);
addIL.Emit(OpCodes.Ret);
到这一步一个动态类包含的属性、构造函数以及方法就创建完成。可以借助reflector看下生成的结果。如下:

public int A { get; set; }
换成
public int A5
{
get { return _a; }
set { _a = value; }
}
比较容易理解_a的存在
二、接口的实现
1、首先我们看下我们要实现一个什么样的接口,先看下构建类的C#代码,示例代码如下:
public class Mail : IMail
{
public string SendMail()
{
return "Send Success";
}
}
public interface IMail
{
string SendMail();
}
2、实现接口,接口我们直接用IMail这个。就不用IL去创建了,首先我们创建一个typeBuilder,指定继承接口IMail,可以用AddInterfaceImplementation来进行操作。示例代码如下:
//定义类型
TypeBuilder typeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public);
typeBuilder.AddInterfaceImplementation(typeof(IMail));
3、实现接口。接口实现方法要怎么定义在不清楚的情况下可以用reflector反编译一个实现接口的方法来查看一下,观察一下方法需要哪些MethodAttributes属性。

通过以上信息可以定义接口实现的方法,接口实现就和之前例子定义的方法实现一样。示例代码如下:
MethodBuilder sendMailBuilder = typeBuilder.DefineMethod("SendMail", MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig, typeof(string), null);
//定义接口
ILGenerator mailIL = sendMailBuilder.GetILGenerator();
LocalBuilder resultStr = mailIL.DeclareLocal(typeof(String));
mailIL.Emit(OpCodes.Nop);
mailIL.Emit(OpCodes.Ldstr, "Send Success1");
mailIL.Emit(OpCodes.Stloc_0);
mailIL.Emit(OpCodes.Ldloc_0);
mailIL.Emit(OpCodes.Ret);
实现后通过IL查看的代码如下:

反编译发现,接口实现是带有override关键字的。而在定义实现方法时候如果不带上virtual属性又会提示接口未实现。。。。。。
通过这篇文章我们了解到了动态类的创建,也了解到了接口的使用。从这两个示例其实可以拓展出很多的东西比如继承、属性绑定自定义标签、虚方法的重写......以后再一一分享
示例代码下载:IL-3
IL接口和类的属性的更多相关文章
- Hibernate(三)__核心接口和类
该图显示了核心接口类以及配置文件的关系层次,越往下越偏向底层数据库. 1. hibernate.cfg.xml文件 ①该文件主要用于指定各个参数,是hibernate核心文件 ②默认放在src目录下, ...
- Servlet API遍程常用接口和类
本文主要总结Servlet API遍程常用接口和类 Servlet API http://tomcat.apache.org/tomcat-5.5-doc/servletapi/index.html ...
- Spring常用的接口和类(二)
七.BeanPostProcessor接口 当需要对受管bean进行预处理时,可以新建一个实现BeanPostProcessor接口的类,并将该类配置到Spring容器中. 实现BeanPostPro ...
- Spring常用的接口和类(一)
一.ApplicationContextAware接口 当一个类需要获取ApplicationContext实例时,可以让该类实现ApplicationContextAware接口.代码展示如下: p ...
- ibernate学习笔记5---实体类或属性名与数据库关键字冲突、hql命名参数、hql实现通用分页
一.实体类或属性名与数据库关键字冲突问题1.实体类名与数据库中的关键字冲突比如:实体表User与oracle中的系统表冲突解决方式1:在xml中添加table属性,指定表名,使其不与name默认相等 ...
- (转)beanUtil接口和类(有空的时候去看,到时候删除这个说明)
Jakarta Commons项目提供了相当丰富的API,我们之前了解到的Commons Lang只是众多API的比较核心的一小部分而已.Commons下面还有相当数量的子项目,用于解决各种各样不同方 ...
- 一张图让你快速学会UML(聚合、组合、依赖、继承、接口、类)
有朋友反映,一上来直接讲设计模式就算理解了,也不知道如何画出类图,那么我们就通过一张图,来图解如何应用UML正确表示类与类之间的关系. 这张图完整讲述了鸟类的生存. 首先是类:在UML中,我们用分成三 ...
- XML之自动生成类,添加,修改,删除类的属性
1. class ClassHelperDemo { public static void Main() { #region 演示一:动态生成类. //生成一个类t. Type t = ClassHe ...
- Spring常用接口和类
一.ApplicationContextAware接口 当一个类需要获取ApplicationContext实例时,可以让该类实现ApplicationContextAware接口.代码展示如下: p ...
随机推荐
- 从零开始编写自己的C#框架(26)——小结
一直想写个总结,不过实在太忙了,所以一直拖啊拖啊,拖到现在,不过也好,有了这段时间的沉淀,发现自己又有了小小的进步.哈哈...... 原想框架开发的相关开发步骤.文档.代码.功能.部署等都简单的讲过了 ...
- 【原创经验分享】WCF之消息队列
最近都在鼓捣这个WCF,因为看到说WCF比WebService功能要强大许多,另外也看了一些公司的招聘信息,貌似一些中.高级的程序员招聘,都有提及到WCF这一块,所以,自己也关心关心一下,虽然目前工作 ...
- 【C#附源码】数据库文档生成工具支持(Excel+Html)
[2015] 很多时候,我们在生成数据库文档时,使用某些工具,可效果总不理想,不是内容不详细,就是表现效果一般般.很多还是word.html的.看着真是别扭.本人习惯用Excel,所以闲暇时,就简单的 ...
- 基于RN开发的一款视频配音APP(开源)
在如今React.ng.vue三分天下的格局下,不得不让自己加快学习的脚步.虽然经常会陷入各种迷茫,学得越多会发现不会的东西也被无限放大,不过能用新的技术作出一些小项目小Demo还是会给自己些许自信与 ...
- 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范
昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...
- C++ 拷贝构造函数和赋值运算符
本文主要介绍了拷贝构造函数和赋值运算符的区别,以及在什么时候调用拷贝构造函数.什么情况下调用赋值运算符.最后,简单的分析了下深拷贝和浅拷贝的问题. 拷贝构造函数和赋值运算符 在默认情况下(用户没有定义 ...
- iOS中支付宝集成
iOS中支付宝集成 如今各种的App中都使用了三方支付的功能,现在将我在使用支付宝支付集成过程的心得分享一下,希望对大家都能有所帮助 要集成一个支付宝支付过程的环境,大致需要: 1>公司:先与支 ...
- C语言可以开发哪些项目?
C语言是我们大多数人的编程入门语言,对其也再熟悉不过了,不过很多初学者在学习的过程中难免会出现迷茫,比如:不知道C语言可以开发哪些项目,可以应用在哪些实际的开发中--,这些迷茫也导致了我们在学习的过程 ...
- javaMail
JavaMail概述: JavaMail是由Sun定义的一套收发电子邮件的API,不同的厂商可以提供自己的实现类.但它并没有包含在JDK中,而是作为JavaEE的一部分. javaMai ...
- 基于AngularJs的上传控件-angular-file-upload
今天跟大家分享的是一个依赖于angular的上传控件. 前段时间做项目遇到一个需求是上传文件,大概需要实现的样式是这样子的,见下图: 需要同时上传两个文件.并且规定文件格式和文件大小.因为前端框架使用 ...