博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 动态解析表达式
阅读量:6620 次
发布时间:2019-06-25

本文共 1950 字,大约阅读时间需要 6 分钟。

需求

我们很难捉摸用户的思维,即使使用非常正式的文档规范某些数据的定义、结果的标准等,也不能抵挡住用户不断变化的需求,但他们有个万变不离的东西——你做这个东西要是万能的,即输入参数类型、个数等发生改变,也得生成出正确的结果。

在编程计算中,很多时候涉及一些公式,用户要求不但能够调整系数、还要能够调整理公式的结构。例如,将2+3-5调整理成2+3*5。我之前使用的解决方案是写一个类,换公式了,就继承它,写一个子类,代码中用反射去调用这个子类,可以解决问题。但是有些麻烦。

解决方案

现决定,用动态来解析公式的方法来解决这个问题。由于时间比较紧张,找到了一个开源的类库ExpressionEvaluator,没有深入研究,不过已经解决了我们的问题。

官网:

使用示例

1.在官网下载ExpressionEvaluator. dll(2.0.4版),在网上搜索antlr3.runtime.dll(3.5.0.2版)

2.项目中引用这两个dll;

3.第一种情况,不需要变量,直接是常规的数字、符号、系统函数(Math类)的组合。

/// /// 简单数值计算/// /// 纯表达式/// 
返回值
public static string SimpleEval(string str){ var types = new TypeRegistry(); types.RegisterDefaultTypes(); var expression = new CompiledExpression(str) { TypeRegistry = types }; var result = expression.Eval(); Console.WriteLine("简单数值计算: {0}", result); return result.ToString();}

  

调用:

SimpleEval(this.textBox1.Text.Trim()

  

结果如下:

4.第二种情况,其中包含了一些变量(这种情况更多),需要将自己的变量写成一个类,然后注册这个类。

public class Result{    public  double Death { get; set; }    public  double Injury { get; set; }}

  

方法:

/// /// 变量字段的计算/// /// /// /// 
public static string FieldEval(string str,Object type){ //注册 var reg = new TypeRegistry(); reg.RegisterSymbol("Result", type); //如果要使用Math函数,还就注册这个 //reg.RegisterDefaultTypes(); //编译 var p = new CompiledExpression(str) { TypeRegistry = reg }; p.Compile(); //计算 Console.WriteLine("变量字段计算: {0}", p.Eval()); return p.Eval().ToString();}

  

调用:

string[] strFields = new string[] { "Death","Injury"};string exp = this.textBox2.Text.Trim();for (int i = 0; i < strFields.Length;i++ ){    if (exp.Contains(strFields[i]))    {        exp= exp.Replace(strFields[i], "Result." + strFields[i]);    }                                }Result re = new Result(){        Death = Convert.ToDouble(this.txtDeath.Text.Trim() + ""),        Injury = Convert.ToDouble(this.txtInjury.Text.Trim() + "")};ExpEvaluator.FieldEval(exp,re)

  

结果:

当然,还有其他内容需要研究、学习!

参考

Github地址:

调用系统的Math函数:

转载地址:http://pfypo.baihongyu.com/

你可能感兴趣的文章
crontab报错
查看>>
docker内存限制
查看>>
动态大小的图片上的超链接
查看>>
总结一下常用的排序,冒泡排序,选择排序,快速排序
查看>>
Sql Server系列:系统函数
查看>>
php5.5 yum源
查看>>
samsungGalaxyS4USB驱动
查看>>
SDN第三次作业
查看>>
java第二次实验作业
查看>>
PHP数据集构建JSON及新数组
查看>>
Android:percent 布局
查看>>
数据库主键
查看>>
Examples For PLSQL Cursors - Explicit, Implicit And Ref Cursors
查看>>
javaweb学习总结(三十八)——事务
查看>>
史上最全的Unity面试题(持续更新总结。。。。。。) 包含答案的Unity面试题...
查看>>
Android -- 仿淘宝广告条滚动
查看>>
swift 数据存储
查看>>
使用apidoc 生成Restful web Api文档——新手问题与解决方法
查看>>
写一本书和找一本书
查看>>
hdu1010 Tempter of the Bone(DFS+剪枝)
查看>>