.NET平台开源项目速览(8)Expression Evaluator表达式计算组件使用
在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,给大家初步介绍了一下Expression Evaluator验证组件。那里只是概述了一下,并没有对其使用和强大功能做深入研究,所以今天就通过一篇简单的文章来预览一下其强大的功能。本文曾在【原创】.NET开源表达式计算组件介绍与使用一文中介绍过一个.NET平台开源的表达式计算组件NCal。不过经过比较还是这个Expression Evaluator比较强大,虽然部分功能有重叠。也都能计算常规的数学表达式。这个组件的功能应该说更加强大吧。同时上次的文章中,也有网友提到了另外一个在github的.NET平台的表达式计算组件DynamicExpresso。
.NET开源目录:【目录】本博客其他.NET开源项目文章目录
本文原文地址:.NET平台开源项目速览(8)Expression Evaluator表达式计算组件使用入门
1.基本功能介绍
Expression Evaluator是一个轻量级的可以在运行时解析C#表达式的开源免费组件。表达式求值应该在很多地方使用,例如一些工资或者成本核算系统,就需要在后台动态配置计算表达式,从而进行计算求值。经过看源代码,这组件是用到了一个Antlr3的开源工具,Antlr3是一个开源的,支持多平台的语法解析器。该组件目前还在更新中,所以值得关注。Expression Evaluator支持的特性有:
*支持算术运算符,支持关系运算符,以及逻辑运算符
*支持表达式分组和括号,以及递增递减运算符
*支持表达式属性访问以及动态类型,支持字符串的+运算
*支持数值类型的后缀d/f/m/l/u/ul、
*支持隐式表达式,以及成员访问操作符(.)
*支持一些默认的类型,如double, float, char, string, DateTime, Convert, Math
*支持foreach循环
等等,更多功能还期待你的使用和发现。下面我们就将介绍该组件的几个典型表达式求值的用途。
官方网站:http://csharpeval.codeplex.com/
2.数学表达式求值
数学表达式求值应该是最常见的,一般我们在应用程序中如果需要计算,是需要对参数进行类型转换,然后在后台进行相应计算的。但是如果是计算一些符合的式子或者公式,特别是参数不一定的情况下,这个就比较麻烦,虽然也有解决办好。但总归是不好。那看看使用 Expression Evaluator的几个简单例子。
使用需要注意的是:需要直接引用ExpressionEvaluator.dll,另外Antlr3.Runtime.dll可以直接引用,也可以直接放到bin目录中,否则会提示找不到依赖文件。以前看到过一个表达式组件也是使用了这个开源的语法分析器。
看看核心代码,使用前引用主要的命名空间:using ExpressionEvaluator;
var expression = new CompiledExpression("1 + 2 + 3 + 4 + 5");
var result = expression.Eval();
Console.WriteLine(result);//结果 15
输出结果是 15,很明显就是2个过程,需要表达式,然后进行Eval分析计算即可。
另外在使用组件时,内部还默认注册了很多.NET值类型,可以直接使用这些类型的静态方法来进行操作。例如可以进行如下解析并执行:
var expression = new CompiledExpression("double.Parse('3.141592654')");
var result = expression.Eval();
Console.WriteLine(result); // 结果是:3.141592654
是可以直接执行double的Parse方法的。目前内置支持的类型:
object/Object,bool/Boolean,byte/Byte,char/Char,short/Int16,int/Int32,long/Int64,ushort/UInt16,uint/UInt32,ulong/UInt64,decimal/Decimal
double/Double,float/Single,string/String
至于布尔类型的判断等也都支持,比较简单,就不详细说了。
下面就看看Expression Evaluator的其他用法。进行简单数值计算,其他很多组件都能办到。
3.注册类型与范围注册类型的成员
在上面例子中,系统内部已经支持了一些数值类型,可以直接进行静态函数的调用解析。但是实际中,我们的业务系统类型肯定千变万化,要满足动态计算的情况,显然上面是不够的。所以Expression Evaluator提供了这种非常给力的操作,将你的实例进行注册后,在表达式中,可以直接使用注册的名称来访问实例的成员变量,然后参与表达式的计算。这样,很多复杂的动态计算功能基本都可以实现了。
看看下面这个例子,具体过程不详细见解,我在注释中写全面一点,看代码就可以理解了:
static void Test()
{
var v = new MyClass();//对象实例化
v.myExternalVar = 6;//字段赋值
//TypeRegistry是核心的类型注册对象
var registry = new TypeRegistry();
//将上面的变量v进行注册,以符号vars替代
registry.RegisterSymbol("vars", v); //表达式计算对象,仔细看里面的变量vars以及直接调用myExternalVar字段
var exp = new CompiledExpression("(vars.myExternalVar + 3) / 2 * 4.5 "); // 设置表达式的类型注册对象为 registry,注意要在eval之前进行设置
exp.TypeRegistry = registry;
Console.WriteLine(exp.Eval());//结果20.25,看看怎么来的? //表达式计算对象,仔细看里面的变量vars以及直接调用myExternalVar字段
var exp2 = new CompiledExpression("vars.getRandomNumber() + 3"); // 设置表达式的类型注册对象为 registry,注意要在eval之前进行设置
exp2.TypeRegistry = registry;
Console.WriteLine(exp2.Eval());//结果为8,5+3
}
上面的MyClass类型的代码如下,很简单:
/// <summary>自定义的实体或者业务类型</summary>
public class MyClass
{
/// <summary>一个指定的double字段</summary>
public double myExternalVar;
//获取double值的一个方法
public double getRandomNumber()
{
return 5;//假设默认返回5
}
}
下面再看一下通过字符串访问数组索引值的方法。
4.通过字符串动态访问数组下标
和上面的例子有部分类似,开阔一下眼界吧,说明其使用是非常灵活的。为了便于演示,我们同样构造一个MyClass2类,代码如下:
public class MyClass2
{
public string[] myExternalString;
public int x;
}
下面是访问获取字符串数组的代码:
var v = new MyClass2();
v.myExternalString = new string[] { "Hello", "there", "World!" };
v.x = 2;
var registry = new TypeRegistry();
registry.RegisterSymbol("v", v); var exp = new CompiledExpression("v.myExternalString[v.x/2]");
exp.TypeRegistry = registry; Console.WriteLine(exp.Eval());//结果there
5.资源
源代码大家可以去官网下载最新的,还是老样子,制作了一份CHM格式的帮助文档。如果打不开的同学,记得右键,属性,解除锁定哦。晒图:

.NET平台开源项目速览(8)Expression Evaluator表达式计算组件使用的更多相关文章
- .NET平台开源项目速览-最快的对象映射组件Tiny Mapper之项目实践
心情小札:近期换了工作,苦逼于22:00后下班,房间一篇狼藉~ 小翠鄙视到:"你就适合生活在垃圾堆中!!!" 晚上浏览博客园 看到一篇非常实用的博客:.NET平台开源项目速览(14 ...
- .NET平台开源项目速览(9)软件序列号生成组件SoftwareProtector介绍与使用
在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,给大家初步介绍了一下Software Protector序列号生成组件.今天就通过一篇简单的文章来预览一下其强大的功 ...
- .NET平台开源项目速览(7)关于NoSQL数据库LiteDB的分页查询解决过程
在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑) 与 .NET平台开源项目速览(3)小巧轻量级NoSQL文件数据库LiteDB中,介绍了LiteDB的基本使用情况以及部 ...
- .NET平台开源项目速览(17)FluentConsole让你的控制台酷起来
从该系列的第一篇文章 .NET平台开源项目速览(1)SharpConfig配置文件读写组件 开始,不知不觉已经到第17篇了.每一次我们都是介绍一个小巧甚至微不足道的.NET平台的开源软件,或者学习,或 ...
- .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...
- .NET平台开源项目速览(13)机器学习组件Accord.NET框架功能介绍
Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET Framework更注重与机器 ...
- .NET平台开源项目速览(1)SharpConfig配置文件读写组件
在.NET平台日常开发中,读取配置文件是一个很常见的需求.以前都是使用System.Configuration.ConfigurationSettings来操作,这个说实话,搞起来比较费劲.不知道大家 ...
- .NET平台开源项目速览(12)哈希算法集合类库HashLib
.NET的System.Security.Cryptography命名空间本身是提供加密服务,散列函数,对称与非对称加密算法等功能.实际上,大部分情况下已经满足了需求,而且.NET实现的都是目前国际上 ...
- .NET平台开源项目速览(11)KwCombinatorics排列组合使用案例(1)
今年上半年,我在KwCombinatorics系列文章中,重点介绍了KwCombinatorics组件的使用情况,其实这个组件我5年前就开始用了,非常方便,麻雀虽小五脏俱全.所以一直非常喜欢,才写了几 ...
随机推荐
- [Android]依赖注入框架google的dagger
分享一下Android依赖注入框架--Google升级版Dagger2框架 Google的Dagger2是对上一版squareup的Dagger改版,话不多说直接上项目代码. Dagger2源码 Da ...
- ThinkPHP框架的一些基础应用
这是俺滴师傅给俺传授了的知识,特在此分享. TP框架,做PHP开发的都应该有所耳闻.下面,我们就来说说入口文件的生成: 创建新项目时,首先,在目录文件下创建一个新的文件夹.然后将Thinkphp框架文 ...
- ASIHTTPRequest取消异步请求
今天碰到一个问题 异步请求等待中 cancel后会发生什么,网上找了下资料说取消的请求默认都会按请求失败处理,并调用请求失败delegate 查找到的资料具体解释了下ASIHTTPRequest取消异 ...
- c# http get请求与post请求实例
//http请求工具类 using System;using System.Collections.Generic;using System.IO;using System.Linq;using Sy ...
- BIT 树状数组 详解 及 例题
(一)树状数组的概念 如果给定一个数组,要你求里面所有数的和,一般都会想到累加.但是当那个数组很大的时候,累加就显得太耗时了,时间复杂度为O(n),并且采用累加的方法还有一个局限,那就是,当修改掉数组 ...
- jsfl调整笔刷的笔触和颜色
今天在用jsfl写脚本以简化对fla资源的处理工作,在画矩形时需要能自动调整笔刷的笔触颜色,填充颜色透明度,查jsfl文档无果,上网查了多番资料写出了可用代码,共享下: var fill = fl.g ...
- hdu 2037简单贪心--活动安排问题
活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子.该问题要求高效地安排一系列争用某一公共资源的活动.贪心算法提供了一个简单.漂亮的方法使得尽可能多的活动 ...
- 命令行操作svn和git和git
前几天在写代码的时候电脑突然坏掉,老大交代的任务没完成,非常痛恨自己用svn或者git保存代码,相信很多程序员遇到过,硬盘坏掉,存在硬盘中的代码丢失,无法找回的问题,svn和git可谓程序员界的福音, ...
- Linux入门之路
一.linux简介 Linux前身:Minix,由Andrew S. Tanenbaum教授参考Unix编写 Linux创始人:Linus Torvalds Linux内核版(只有内核)和发行版(在内 ...
- php将html转成word文档下载
<meta charset="utf-8" /> <?php class word{ function start(){ ob_start(); echo '&l ...