评估数学表达式的最佳和最短方法
There are many algorithms to evaluate expressions, for example:
Is there any way to evaluate any mathematical expression using C# .net reflection or other modern .net technology?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
根据 Thomas 的回答,实际上可以直接从 C# 访问(已弃用的)JScript 库,这意味着您可以使用 JScript 的
eval
函数的等效功能。Further to Thomas's answer, it's actually possible to access the (deprecated) JScript libraries directly from C#, which means you can use the equivalent of JScript's
eval
function.这当然是可能的。 CodeSnippetCompileUnit 类基本上执行此操作。
我给你写了一些示例使用代码。您需要包含以下命名空间:
代码如下:
将“参数”和“表达式”替换为任何内容,您就得到了一个通用表达式求值器。
如果您在 results.CompiledAssembly 中收到 FileNotFoundException,则该代码段无法编译。
您可能还想查看 System.CodeDom.CodeSnippetExpression 类。它用于更具体地读取表达式,但表达式本身无法编译,因此您需要使用更多 CodeDom 来围绕它构建工作类和方法。如果您希望能够以编程方式操作正在生成的类的类型,这非常有用。 CodeSnippetCompileUnit 很适合一次生成整个工作类(对于示例来说更简单),但要操作它,您将不得不进行不方便的字符串操作。
It's certainly possible. The CodeSnippetCompileUnit class does basically this.
I wrote you some example usage code. You'll need to include these namespaces:
Here's the code:
Replace 'parameters' and 'expression' by whatever, and you've got yourself a general expression evaluator.
If you get a FileNotFoundException in results.CompiledAssembly, then the snippet failed to compile.
You might also want to take a look at the System.CodeDom.CodeSnippetExpression class. It's used for more specifically reading expressions, but an expression by itself can't be compiled, so you would need to use more CodeDom to build a working class and method around it. This is useful if you want to be able to programmatically manipulate what kind of class you're generating. CodeSnippetCompileUnit is nice to generate an entire working class at once (and simpler for an example) but to manipulate it you would have to do inconvenient string manipulations.
ncalc 是最好的。您可以在 codeplex 中找到它,也可以在 nugget 中找到它。
NCalc 是 .NET 中的数学表达式计算器。 NCalc 可以解析任何表达式并计算结果,包括静态或动态参数以及自定义函数。
ncalc is the best. you can find it in codeplex also in nugget.
NCalc is a mathematical expressions evaluator in .NET. NCalc can parse any expression and evaluate the result, including static or dynamic parameters and custom functions.
尽管使用编译器服务是一种简单而有效的解决方案,但如果用户输入表达式,则会引发严重的安全问题,因为它实际上可以执行任何东西。
还有另一个非常简单但更安全的解决方案:利用 JScript
Eval
函数。您只需要按照以下步骤操作:创建一个名为 JsMath.js 的 js 文件:
将其编译成类库:
在 C# 项目中引用 JsMath 库,然后像这样使用它:
Although using compiler services is a simple and efficient solution, it raises serious security issues if the expression is entered by a user, because it could execute virtually anything.
There's another very simple solution that is much more secure : take advantage of the JScript
Eval
function. You just need to follow these steps :Create a js file named JsMath.js :
Compile it into a class library :
Reference the JsMath library in your C# project, and use it like that :
对我来说,Vici.Parser 工作得非常好:在这里查看,它是最灵活的到目前为止我找到的表达式解析器。
(我们使用它来设置“人类可读”的业务规则,并使用 SQL 服务器数据库提供的数据)
提供了示例,并且开发人员提供了非常好的支持(查看网站的论坛)。
For me Vici.Parser works extremely well: check it out here , it's the most flexible expression parser I've found so far.
(we've used it to set up 'human-readable' business rules, with data provided by an SQL server database)
Examples are available and there's a very good support by the developer (check the website's forum).
我认为这是最好的方法。 Petar Repac 的回答令人惊叹。
使用 DataColumn 对象的“表达式”参数可以非常轻松地解决该主题:
I think this is the best way of all. Petar Repac's answer is amazing.
Using the 'expression' argument of the DataColumn object solves incredibly and easily the topic:
您可以使用 Math-Expression-Evaluator 库,它实现了我作者的 Shunting Yard 算法的。支持
2.5+5.9
、17.89-2.47+7.16
、5/2/2+1.5*3+4.58
、表达式等简单表达式带括号(((9-6/2)*2-4)/2-6-1)/(2+24/(2+4))
和带变量的表达式:您还可以将参数作为命名变量传递:
它支持 .Net Standard 2.0,因此可以在 .Net Core 以及 .Net Full Framework 项目中使用,并且没有任何外部依赖项。
You can use Math-Expression-Evaluator library which implements Shunting Yard algorithm that I am author of. It supports simple expressions such as
2.5+5.9
,17.89-2.47+7.16
,5/2/2+1.5*3+4.58
, expressions with parentheses(((9-6/2)*2-4)/2-6-1)/(2+24/(2+4))
and expressions with variables:You can also pass parameters as named variables:
It supports .Net Standard 2.0 so can be used from .Net Core as well as .Net Full Framework projects and it doesn't have any external dependencies.
使用新的 Roslyn API 动态编译代码,并将程序集加载到 .net core 项目中;
请注意,以及您正在编译的源所需的任何其他类型。为了在同一进程中加载已编译的程序集,引用需要包括:
To dynamically compile code using the new Roslyn API's, and load the assembly in a .net core project;
Note that along with any other types required by the source you are compiling. In order to load the compiled assembly within the same process, references will need to include;