
1. 说明:
先看看我们的结果:

Internet上有很多表达计算器,但是这次我们有一些要点,不同的是,有两点:
1)用户可以进行编程以扩展计算器的功能
那是右下角的“添加功能按钮”
例如,如果要添加“ Factarial”阶乘函数,则可以“添加函数”

然后编辑我们的功能

最后“生成”,将在主窗口中自动添加一个“ Factarial”按钮,然后可以使用它(该功能将一直存在,除非您手动将其删除)
实际上,主窗口中的所有功能按钮都是以这种方式生成的
2)我们对表达式的计算将摆脱传统的观点(即传统的词法分析,语法分析等)c#编程设计,并且计算器代码,语法分析c#编程设计,后缀中将没有词法分析表达式转换等.
等等.
灵感来自这里:
假设有一个函数F
双F()
{
double r = 3 * 4.5 + sin(50);
返回r;

}
因此,我们可以使用Console.WriteLine(“ {0}”,F());
我们计算出3 * 4.5 + sin(50),但是是否进行了麻烦的词法分析和语法分析?不,是谁帮助了我们,编译器,好的,关键就在这里: 如果计算器用户在计算器主窗口中输入了一个表达式
3 * 4.5 + sin(50),我们负责将其传递给F中的r,然后将F的返回值输出到用户界面,这没关系,我们要做的就是这个.
计算器上的2种功能
2.1功能按钮对应的功能在哪里?
在Functions.dll中,不要指望微软将其提供给我,因为该功能是由用户编写的,我们不知道用户将编写哪种功能,他甚至可以编写播放音乐的功能(呵呵,我们的计算器
这可以做到,但是对于计算器来说似乎太多了
2.2谁负责生成Functions.dll?
不是.net2003,不是.net2005,我们的计算器
要在用户定义函数时将函数打包到Functions.dll中,涉及编译问题,我们将负责这项工作
2.3谁赋予了我们编译权?
我们的答案在System.CodeDom.Compiler和Microsoft.CSharp命名空间中(请参见Msdn)
Functions.dll成功打包后,我们可以在计算表达式中调用该函数
3表达式的计算
3.1如何计算?
在前面的计算3 * 4.5 + sin(50)的示例中,已经说过我们将使用编译器来帮助我们进行计算,就像Console.WriteLine(“ {0}”,F ())向用户输出函数F的返回值(F的返回值是表达式的值):
双F()
{
双倍经验= 3 * 4.5 +罪恶(50); //假设3 * 4.5 + sin(50)是用户输入的表达式

返回exp;
}
3.2 F()来自哪里?去哪里?
F()一定不是我们预先编写的,因为exp的初始表达式是由用户编写的
我们将以这种方式解决此问题: 用户输入表达式后,动态生成函数F()->编译代码->在编译的程序集中调用该函数
/// <摘要>
///将数学表达式转换为C#程序
/// summary>
/// 用户输入的数学表达式 param>
///
公共静态字符串TranslateToCSharp(字符串表示形式)
{
string s =“”;
如果(File.Exists(Function.GetPathOfFunctionDll()))
{
s + =“ using” + Function.FunctionNameSpace +“; \ n”;
}
s + =
“正在使用系统; \ n” +
“命名空间ComputeUnit \ n” +

“ {\ n” +
“公共类计算\ n” +
“ {\ n” +
“公共静态双GetResult()\ n” +
“ {\ n” +
“返回” + TranslateToCSharpExpress(表达)+“; \ n” +
“} \ n” +
“}” +
“} \ n”;
返回s;
}
这里的GetResult()函数就是我们所说的函数F()
3.3谁帮助我们获得了计算结果?
反思!
假设用户输入了表达式express,我们将按照以下代码进行计算
字符串源= TranslateUnit.TranslateToCSharp(表示);
//功能dll在这里加载
字符串[] dll =新字符串[1];
dlls [0] = Function.GetPathOfFunctionDll(); //上面提到的Functions.dll在这里加载
//编译
CompilerResults结果= CompilerUnit.Compile(源,false,true,dll,null);
//重要提示: 使用反射获取计算结果
如果(results.Errors.Count == 0)
{
Assembly ass = results.CompiledAssembly;
Type tp = ass.GetType(“ ComputeUnit.Compute”); // ass.GetType(“ MyNamespace.MyClass”);
//如何获取
MethodInfo mi = tp.GetMethod(“ GetResult”); // tp.GetMethod(“ MyMethodl”);
//创建一个实例
Object obj = System.Activator.CreateInstance(tp);
//执行方法
尝试
{
object res = mi.Invoke(obj,null);
this.Output(res.ToString(),false,Color.Blue); //将计算结果输出给用户
}
捕获(异常除外)
{
MessageBox.Show(例如ToString());
}
以上仅简要描述了该程序的核心问题. 此外,还有许多细节. 如果您需要了解更多信息,可以下载带有详细注释的该程序的源代码.
p>
或电子邮件: yinhui_zhou@yahoo.com.cn与我联系
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-175094-1.html
美国只是虚张声势