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 ...
随机推荐
- python开发环境搭建
虽然网上有很多python开发环境搭建的文章,不过重复造轮子还是要的,记录一下过程,方便自己以后配置,也方便正在学习中的同事配置他们的环境. 1.准备好安装包 1)上python官网下载python运 ...
- Web安全相关(三):开放重定向(Open Redirection)
简介 那些通过请求(如查询字符串和表单数据)指定重定向URL的Web程序可能会被篡改,而把用户重定向到外部的恶意URL.这种篡改就被称为开发重定向攻击. 场景分析 假设有一个正规网站http:// ...
- VC中的MFC到底是什么?
1. 微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是一个微软公司提供的类库(class libraries),以C++类的形式封装了Windows API ...
- FineBI:一个简单易用的自助BI工具
过去,有关企业数据分析的重担都压在IT部门,传统BI分析更多面向的是具有IT背景的人员.但随着业务分析需求的增加,很多公司都希望为业务用户提供自助分析服务,将分析工作落实到业务人员手中.但同时,分析工 ...
- 微信小程序监控 - HotApp统计
HotApp小程序统计,第一个专业的微信第三方小程序监控统计工具 1.什么是HotApp小程序统计 HotApp小程序统计是第一个微信第三方小程序统计工具,就像做android 和 ios开发的人知道 ...
- iOS开发--ChildViewController实现订单页的切换
先不说废话, 上效果图, 代码量也不大, 也不上传github骗星星了, 你们复制粘贴下代码, 就可以轻而易举的弄出一个小demo. 这个代码的实现并不复杂, 甚至于说非常简单, 就是逻辑有点小绕, ...
- 解决Ubuntu Kylin 1610安装ANSYS17.2的NVIDIA显卡驱动问题
Ubuntu Kylin 1610在安装完毕后,会自动安装显卡驱动,对于一般的图形图像使用来说自然不会有太大的问题,但是对于ANSYS17.2的一些模块,还是会出现问题.一个比较常见的问题就是Open ...
- JS案例之3——倒计时
利用简单的数字累加循环模拟倒计时的效果,逻辑比较简单.如果大牛们有更好的办法欢迎补充. 这种效果经常用于在规定的时间做某件事.比如在1分钟之后重新发送验证码等. 案例演示: 源代码如下: <!D ...
- 在树莓派Raspbian下安装支持Hard Float的.NET环境
[题外话] 最近入了个树莓派玩,系统装的官方推荐的Hard Float的Raspbian,由于衍生自Debian,所以Mono什么的非常好装.但是官方源中的Mono在Hard Float的Raspbi ...
- Java的异步HttpClient
上篇提到了高性能处理的关键是异步,而我们当中许多人依旧在使用同步模式的HttpClient访问第三方Web资源,我认为原因之一是:异步的HttpClient诞生较晚,许多人不知道:另外也可能是大多数W ...