【awesome-dotnet-core-learning】(2)-Sprache.Calc-表达式计算器
【awesome-dotnet-core-learning】(2)-Sprache.Calc-表达式计算器
示例代码托管在GITHUB上, 欢迎STAR!
严格来说, Sprache.Calc只是上一篇Sprache-解析器构建库中介绍的Sprache的一个扩展库,而且未罗列在awesome-dotnet-core中.但是表达式计算在很多应用中都有需求,所以单独写一篇博客介绍它.
简介
Sprache.Calc提供了简单易用的表达式计算器功能.可将输入的字符串做为一个表达式,转换成结构化的LINQ表达式,并且可被编译为可执行的委托.
特点
- 支持算术运算, 自定义函数和参数
- 转换为LINQ表达式
- 可编译成委托并执行
- 因为可编译成委托,所以性能上与原生C#相同
快速上手
以下示例演示了用Sprache.Calc编写一个计算表达式的程序.并演示了自定义函数和参数的使用方法.
创建一个.NET Core的命令行应用程序(详细步骤略)
使用Nuget安装Sprache.Calc:
Install-Package Sprache.Calc
在
Program.cs
中,首先创建一个表达式计算器:private static readonly XtensibleCalculator Calculator = new XtensibleCalculator();
编写一个辅助方法,用于编译,执行输入的文本,并输出结果
/// <summary>
/// 运行表达式,输出计算结果
/// </summary>
/// <param name="text">文本</param>
/// <param name="parameters">参数</param>
private static void RunExpression(string text, params Expression<Func<double, double>>[] parameters)
{
var expr = Calculator.ParseExpression(text, parameters);
var func = expr.Compile();
Console.WriteLine($"{text} = {func()}");
}
首先使用XtensibleCalculator的
ParseExpression
方法解析文本表达式, 该方法返回值为Expression<Func<double>>
类型.所以可以使用Compile
方法继承编译为Func<double>
, 最后直接执行即可得到计算结果.parameters
用于接收表达式中的参数.每一个都是一个Func<double, double>
类型委托,如没有参数,可不传递.在
Main
方法中,就可调用RunExpression
了,首先我们测试基本的四则运算:// 四则运算
RunExpression("1 + 2 * 3");
RunExpression("(1 + 2) * 3");
输出结果:
1 + 2 * 3 = 7
(1 + 2) * 3 = 9
可注意到运算符的优先级和括号都是支持的.
测试自定义函数:
// 自定义函数
// 这里注册了一个名为"阶乘"的函数,用来计算一个数的阶乘
Calculator.RegisterFunction("阶乘", n =>
{
// n的阶乘 = n * (n-1) * (n-2) * ... * 1
int r = 1;
for (int i = (int) n; i > 0; i--) r *= i;
return r;
});
RunExpression("阶乘(3) + 阶乘(4)");
我们通过
RegisterFunction
方法注册了一个名为"阶乘"的函数(是的自定义函数名可以为中文),然后通过Lambda函数提供了计算逻辑.这样在表达式中就可以使用我们的自定义函数了.输出结果:
阶乘(3) + 阶乘(4) = 30
测试参数
// 参数
RunExpression("阶乘(a) + 阶乘(b)", a => 4, b => 5); // 将4代入a, 5代入b
我们将表达式中的参数,通过lambda表达式赋值,这样在运行时,该参数的值就会参与计算了.
输出结果:
阶乘(a) + 阶乘(b) = 144
类似库
【awesome-dotnet-core-learning】(2)-Sprache.Calc-表达式计算器的更多相关文章
- dotNet Core开发环境搭建及简要说明
一.安装 .NET Core SDK 在 Windows 上使用 .NET Core 的最佳途径:使用Visual Studio. 免费下载地址: Visual Studio Community 20 ...
- dotnet core 使用 MongoDB 进行高性能Nosql数据库操作
好久没有写过Blog, 每天看着开源的Java社区流口水, 心里满不是滋味. 终于等到了今年六月份 dotnet core 的正式发布, 看着dotnet 社区也一步一步走向繁荣, 一片蒸蒸日上的大好 ...
- dotnet Core Asp.net 项目搭建
Asp.Net Core 介绍 Asp.Net Core 目前最新版本 1.0.0-preview2-003131 Asp.Net Core官网:https://dotnet.github.io/ A ...
- DotNet Core 介绍
前言 asp.net core rtm 6月底即将发布,自己也想着为社区做点共享,刚好最近不太忙,看到社区的小伙伴们都在为dotnet core的推广而贡献力量,项目中刚好在用rc2版本,就多写些文章 ...
- dotnet core 出现Can not find runtime target for framework '.NETCoreApp,Version=v1.6' 的解决办法
如果你在更新dotnet core新的类库后运行程序提示如下的错误: Can not find runtime target for framework '.NETCoreAPP, Version=v ...
- DotNet Core 1.0 集成 CentOS 开发与运行环境部署
一. DotNet Core 1.0 开发环境部署 操作系统安装 我们使用CentOS 7.2.1511版本. 安装libunwind库 执行:sudo yum install libunwi ...
- ubuntu15.10 或者 16.04 或者 ElementryOS 下使用 Dotnet Core
这里我们不讲安装,缺少libicu52自行安装. 安装完成后使用dotnet restore或者build都会失败,一是报编译的dll不适合当前系统,二是编译到ubuntu16.04文件夹下会产生一些 ...
- 北京时间28号0点以后Scott Hanselman同志台宣布dotnet core 1.0 rtm
今日占住微信号头条的好消息<终于来了!微软.Net Core 1.0下载放出>.本人立马跑到官网http://dot.net看了一下,仍然是.net core 1.0 Preview 1版 ...
- DotNet Core 之旅(一)
1.下载安装 DotNetCore.1.0.0-SDK.Preview2-x64.exe 下载链接:https://www.microsoft.com/net/download ps:如果有vs201 ...
- dotnet core 开发体验之Routing
开始 回顾上一篇文章:dotnet core开发体验之开始MVC 里面体验了一把mvc,然后我们知道了aspnet mvc是靠Routing来驱动起来的,所以感觉需要研究一下Routing是什么鬼. ...
随机推荐
- Python:每日一题004
题目: 输入某年某月某日,判断这一天是这一年的第几天? 程序分析: 以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天,特殊情况,闰年且输入月份大于2时需考虑多加一天 个人的思路及 ...
- JavaScript 高阶函数
高阶函数的英文叫Higher-order function ,什么是高阶函数呢>? JavaScript的函数其实都指向某个变量.既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接 ...
- 【NIFI】 Apache NiFI 之 ExecuteScript处理(二)
本例介绍NiFI ExecuteScript处理器的使用,使用的脚本引擎ECMScript 接上一篇[NIFI] Apache NiFI 之 ExecuteScript处理(一) ExecuteScr ...
- mysql 在update中实现子查询的方式
当使用mysql条件更新时--最先让人想到的写法 UPDATE buyer SET is_seller=1 WHERE uid IN (SELECT uid FROM seller) 此语句是错误的, ...
- tensorflow学习之(四)使用placeholder 传入值
#placeholder 传入值 import tensorflow as tf """ tf.Variable:主要在于一些可训练变量(trainable variab ...
- js将数组根据条件分组
//将数组根据条件分组 function getTreeDateByParam(list, param, fun){ var data = {}; if(list && list.le ...
- drf8 解析器
解析器的介绍 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己想要的数据类型的过程. 本质就是对请求体中的数据进行解析. Accept与ContentType请求头. Accept是告诉 ...
- poj 3279(暴力)
题意:有一个n*m的格子,每个格子都有黑白两面(0表示白色,1表示黑色).我们需要把所有的格子都反转成黑色,每反转一个格子,它上下左右的格子都会跟着反转.请求出用最小步数完成反转时每个格子反转的次数. ...
- 用jstack自动化捕抓异常java代码脚本
#!/bin/bashdate=` date +%y%m%d-%H%M`pid=`top -bn1 |grep java | awk '{print $1 "\t" $9}' |h ...
- [翻译] FastReport TfrxReport组件使用
一:加载和保存报表 报表默认保存在项目窗体文件中,大多数情况下,没有更多的操作要深圳市, 因此,你不需要采取特别措施来载入报告.如果你决定保存报表到文件或是数据库中 (这样更灵活, 比如修改报表不用重 ...