C# 反射,动态编译
反射是动态获取程序集的元数据的一种技术,这句话是做.NET程序员面试题目的一个的答案,你可选择记住它,就好比高中生物学里面讲到的细胞的结构的课程时,细胞由细胞膜,细胞质和细胞核组成。根据做程序的经验,Never ask why不是好习惯,即使是微软的API,有时候违反了调用约定,也会很抓狂。
请看下面这一段代码
Assembly assembly = Assembly.GetExecutingAssembly();
object entryForm = Activator.CreateInstance(formBaseType) as Form;
entryForm .MdiParent = this;
entryForm .Show();
entryForm .Activate();
代码的含义比较简单,从当前程序集中创建formBaseType类型,并调用它的方法。从方法名上来看,大概可以看出,这是一段MDI创建child子窗体,并显示子窗体的代码。
这段小代码,也是插件式框架的基本思路,请参考《Management Console 工具管理类软件通用开发框架(开放源码)》中的例子来体会它的用处。
在ERP/MIS系统中,应用反射的例子,实在是太多了。数据访问接口InventoryMovementDAL,借助于反射,来查找并调用它的实现类; 窗体也它的子窗体借助于反射来获取属性,传递值;ERP系统的整个框架,也是借助于反射搭建起来.
看下面的图,ERP的三个模块Paradox.ERP.SystemAdministration, Paradox.ERP.Engineering,Paradox.ERP.Inventory被Paradox.Framework.Kernal反射调用,如果再写一个Paradox.ERP.Sales的销售模块,几乎不需要改动,就可以让它被框架调用。

动态编译的例子,是应用到一个工资系统中. 请看图 
对于如何解析工资的formular公式,有若干种办法,这里使有的是动态编译的方法。把每一个工资项看成是一个类型class的属性,Formular的内容则放到一个方法中去,当成表达式计算求职,最后应用反射,返回各属性的值即可。
public class FormularCalculation
{
public static object Build(string[] items, string formular)
{
string nameSpace = "A";
string className = "FormularCalculation";
string methodName = "Run";
CSharpCodeProvider compiler = new CSharpCodeProvider();
CompilerParameters paras = new CompilerParameters();
paras.GenerateExecutable = false;
paras.GenerateInMemory = true;
StringBuilder classSrc = new StringBuilder();
classSrc.Append(" using System;"+Environment.NewLine);
classSrc.Append(" namespace "+nameSpace+" { " + Environment.NewLine);
classSrc.Append("public class " + className + "{ " + Environment.NewLine);
foreach (string item in items)
{
classSrc.Append("public decimal " + item + ";" + Environment.NewLine);
}
classSrc.Append("public void Run() { 基本工资=5000; " + Environment.NewLine);
string [] format= Regex.Split(formular,Environment.NewLine);
foreach (string prop in format)
{
classSrc.Append(prop +" ;"+ Environment.NewLine);
}
classSrc.Append("}"+Environment.NewLine);
classSrc.Append("}" + Environment.NewLine);
classSrc.Append("}" + Environment.NewLine);
string source = classSrc.ToString();
CompilerResults result = compiler.CompileAssemblyFromSource(paras, source);
CompilerErrorCollection error= result.Errors;
Assembly assembly = result.CompiledAssembly;
object eval = assembly.CreateInstance(nameSpace+"."+className);
MethodInfo method = eval.GetType().GetMethod(methodName);
object reobj = method.Invoke(eval, null);
return eval;
}
}
调用方法如下
string[] items = { "应发合计","基本工资","奖金","福利费", "扣款合计","社保","税","实发合计","应税所得额"};
string formular=@ ” 应发合计=基本工资+ 奖金 + 福利费 - 扣款合计;
扣款合计=社保 + 税+ 应税所得额;
实发合计=应发合计- 扣款合计; ";
object obj = FormularCalculation.Build(items, formular);
Type type = obj.GetType();
foreach (PropertyInfo fi in type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
string value = fi.Name; //取到计算后的各个属性的值
}
动态编译还应用于软件的加密,在内存中产生加密程序的源代码,动态编译并运行,检测是否符合license授权。
C# 反射,动态编译的更多相关文章
- Java学习:注解,反射,动态编译
狂神声明 : 文章均为自己的学习笔记 , 转载一定注明出处 ; 编辑不易 , 防君子不防小人~共勉 ! Java学习:注解,反射,动态编译 Annotation 注解 什么是注解 ? Annotat ...
- 反射已经"Out",动态编译才能"Hold"住
Net支持反射功能以后,确实使我们Net程序眼前一亮啊,真是太神奇了,只需要传入字符串就可以完成功能.可以说,反射功能的引入,使我们在处理某些问题上更加得心应手. 传统的Db管理软件中,数据库字段的频 ...
- (转载)JAVA动态编译--字节代码的操纵
在一般的Java应用开发过程中,开发人员使用Java的方式比较简单.打开惯用的IDE,编写Java源代码,再利用IDE提供的功能直接运行Java 程序就可以了.这种开发模式背后的过程是:开发人员编写的 ...
- java动态编译笔记
1 前言 Java的动态编译知识,真真在实际开发中并不是经常遇到.但是学习java动态编译有助于我们从更深一层次去了解java.对掌握jdk的动态代理模式,这样我们在学习其他一些开源框架的时候就能够知 ...
- 重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译
多年前用过李天平前辈的,自己改过,后来李老师做动软了,不给源码,修改不是很方便.加上我目前需要转java方向,于是决定自己搞.到目前为止花了整整一个星期了,看看目前的成果. 最后是代码工程文件,用c# ...
- 浅谈VB.Net 程序的编译和动态编译
---恢复内容开始--- 一般,我们都是通过Visual Studio(下面简称vs)来编写和编译vb.net应用程序的,但是,不少的人并不知道vs是通过何种方式编译程序的.今天,我们就来探讨一下编译 ...
- .NET中的动态编译
代码的动态编译并执行是一个.NET平台提供给我们的很强大的工具用以灵活扩展(当然是面对内部开发人员)复杂而无法估算的逻辑,并通过一些额外的代码来扩展我们已有 的应用程序.这在很大程度上给我们提供了另外 ...
- Java_Java SE6调用动态编译
转自:http://www.cnblogs.com/flyoung2008/archive/2011/11/14/2249017.html 一.使用JavaCompiler接口编译java源程序 我们 ...
- .net 动态编译解决考勤计算问题
由于公司实施SAP HR项目,但是SAP HR对考勤功能真的太弱化了,直接从考勤机上读取的原始打卡记录不能直接传输到HR系统里面,因为SAP HR不能识别那些多余的打卡记录,而且必须把打卡记录进行成组 ...
随机推荐
- oracle定时器在项目中的应用
业务需求: 现在业务人员提出了一个需求: 在项目中的工作流,都要有一个流程编号,此编号有一定的规则: 前四五位是流程的字母缩写,中间是8位的日期,后面五位是流水码,要求流水码每天从00001开始.即: ...
- python 实现查找某个字符在字符串中出现次数,并以字典形式输出
把字符串'aenabsascd'中的字符出现的次数统计出来,并以字典形式输出 方法一: def count_str(str): dic={} for i in str: dic[i]=str.coun ...
- fail2ban 防暴力破解总结
公司服务器安全问题一直是个令人头疼的问题,许多运维的小伙伴一直在用脚本来监控服务器登录状态,然而脚本编写比较麻烦,今天就给大家推荐一款小而精致的防暴力破解工具 fail2ban ,他可以监控系统日志, ...
- Linux(CentOS7)设置自动备份数据库到阿里云OSS
环境:阿里云服务器CentOS7.4 + MySQL5.6 基本思路: 1.编写shell脚本,备份数据库到指定目录下 2.编写Python脚本,把文件上传到OSS 3.把shell脚本和Python ...
- 一条SQL语句的千回百转
SQL语言相信大家都不陌生,从本质上来说,它是一种结构化查询语言,是用来数据库之间的通信的编程语言.作为一名Java程序员,我们从Java角度来看,SQL语言相当于Java接口,而数据库是实现这个接口 ...
- HIve数据存储
表 Table 内部表 Partition 分区表 External Table 外部表 Bucket Table 桶表 内部表 分区表 parttion对应于数据库中的Partition列的密集索引 ...
- 树莓3B+_root密码开启
开启root用户的方法:1.设置密码:sudo passwd2.sudo passwd --unlock root3.root用户登录:su
- C语言顺序队列
顺序队列是一种只能在一头进和另一头出的数据结构,所以结构体里设2个指针分别指向头部和尾部,用数组来存储数据. #define MAXSIZE 1024 typedef int elemtype; ty ...
- PTA基础编程题目集6-5求自定类型元素的最大值 (函数题)
原题目: 本题要求实现一个函数,求N个集合元素S[]中的最大值,其中集合元素的类型为自定义的ElementType. 函数接口定义: ElementType Max( ElementType S[], ...
- 20155305 2016-2017-2 《Java程序设计》实验四 Android开发基础设计实验报告
实验内容 1.Android Stuidio的安装测试: 参考<Java和Android开发学习指南(第二版)(EPUBIT,Java for Android 2nd)>第二十四章: 安装 ...