序言:前几天整理资料时发现以前翻译的一篇关于CodeDom的文章,虽然题材比较老了,但还是可能对部分兄弟有用,贴出来与大家共享,不妥之处敬请指出。原文来自CSharpCorner:http://www.c-sharpcorner.com/UploadFile/mgold/CodeDomCalculator08082005003253AM/CodeDomCalculator.aspx
介绍:
借助CodeDom和Reflection我们可以动态编译C#代码并使之在程序中任何地方都能运行。这个强大的特性允许我们创建在Windows窗体甚至C#代码行中都可以运算数学表达式的CodeDom计算器。首先我们需要借助System.Math类来进行计算,但我们并不需要在算式前加上Math. 前缀,下面将向您展现CodeDom计算器是如何实现的。
图 1 – 运行中的CodeDom计算器
用法:
CodeDom可依下列两种方法使用:
1、用C#语法输入你要计算的数学表达式
2、写一个计算复杂算式的C#代码块
第一种方法仅需要按图2中的方法输入算式即可。
图 2 – 在CodeDom计算器中运算一个较长的算式
在第二种方法中我们实现的手段略有差异。最上面一行写一个answer加上分号,之后你就可以写任何C#代码,在代码片断的末端将你需要得到的答案赋予answer变量。在写代码时同上也不用加Math类前缀,图3是用CodeDom求从1到10的和的示例:
图 3 – 用CodeDom计算从1到10的和
创建并运行Calculator类
运算表达式的下面几步是:
1、使用CodeDom依据算式创建C#代码
2、使用CodeDom编译器将这段代码编译为程序集
3、创建一个Calculator类的实例
4、调用Calculator类中的Calculate方法得到答案
下表就是我们要创建的CodeDom类,Calculate方法将包含我们输入CodeDom计算器的数学表达式。
图 4 – UML反工得到的Calculator类
事实上图3中用到的CodeDom程序集是由下列代码创建的。下一节我们将讲述更多关于如何创建包含CodeDom所有方法的类,这些方法真是酷毙了。真如您所见,我们的表达式被传入Calculate方法中。我们需要将answer;放到第一行是为了在Calculate方法强制置入一个哑元行来引入较大的代码块(这个哑元行是Answer = answer;)。如果我们输入一个简单的表达式如1+1,在代码内将产生一行Answer = 1 + 1;
列表 1 – CodeDom为计算器产生的代码
namespace ExpressionEvaluator { using System; public class Calculator /// Default Constructor for class
// The Answer property is the returned result set /// Calculate an expression return this.Answer; } |
代码分析
点击计算按钮后, 代码产生、编译、运行。 列表2 展示了按顺序执行这几步的calculate event handler。尽管这不是全部的代码,所有的步骤已经在BuildClass, CompileAssembly和RunCode方法里全部包括:.
列表 2 – 计算数学表达式的Event Handler
private void btnCalculate_Click(object sender, System.EventArgs e) // change evaluation string to pick up Math class members // build the class using codedom // compile the class into an in-memory assembly. // write out the source code for debugging purposes
// if the code compiled okay, |
CodeDom看起来怎么样呢? 如果你仔细观察过CodeDom中的类, 就会发现它们几乎就是违反语法的。每个构造器使用其他CodeDom对象来构造自己并构造其他语法片断的合成物。表1展示了我们在这个工程中构造程序集用到的所有类和他们各自的用途。
CodeDom 对象 |
用途 |
||
CSharpCodeProvider |
生成C#代码的Provider |
||
CodeNamespace |
构造名称空间的类 |
||
CodeNamespaceImport |
创建调用申明 |
||
CodeTypeDeclaration |
创建类结构 |
||
CodeConstructor |
创建构造器 |
||
CodeTypeReference |
创建一个类型的引用 |
||
CodeCommentStatement |
创建C#注释 |
||
CodeAssignStatement |
|