zoukankan      html  css  js  c++  java
  • 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的销售模块,几乎不需要改动,就可以让它被框架调用。

    image 

    动态编译的例子,是应用到一个工资系统中. 请看图 
    image

    对于如何解析工资的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授权。 

  • 相关阅读:
    组合算法问题
    递归之全排列问题
    递归之整数划分问题
    利用Python完成一个小游戏:随机挑选一个单词,并对其进行乱序,玩家要猜出原始单词
    对数组元素进行排序的方法总结(利用C++)
    用c++语言编写函数 int index(char *s,char * t),返回字符串t在字符串s中出现的最左边的位置,如果s中没有与t匹配的子串,则返回-1。类似于索引的功能。
    用MFC完成一个简单的猜数字游戏: 输入的四位数中,位置和数字都正确为A,数字相同而位置不同的为B。
    用Matlab完成:从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
    利用matlab实现以下功能:将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
    白书_倒三角形_C语言描述
  • 原文地址:https://www.cnblogs.com/ziyan22/p/5550451.html
Copyright © 2011-2022 走看看