如何动态计算 C# 表达式?
我想做相当于:
object result = Eval("1 + 3");
string now = Eval("System.DateTime.Now().ToString()") as string
按照 Biri 的 链接,我得到了这个代码片段(修改为删除过时的方法 ICodeCompiler.CreateCompiler()
:
private object Eval(string sExpression)
{
CSharpCodeProvider c = new CSharpCodeProvider();
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
StringBuilder sb = new StringBuilder("");
sb.Append("using System;\n");
sb.Append("namespace CSCodeEvaler{ \n");
sb.Append("public class CSCodeEvaler{ \n");
sb.Append("public object EvalCode(){\n");
sb.Append("return " + sExpression + "; \n");
sb.Append("} \n");
sb.Append("} \n");
sb.Append("}\n");
CompilerResults cr = c.CompileAssemblyFromSource(cp, sb.ToString());
if (cr.Errors.Count > 0)
{
throw new InvalidExpressionException(
string.Format("Error ({0}) evaluating: {1}",
cr.Errors[0].ErrorText, sExpression));
}
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");
Type t = o.GetType();
MethodInfo mi = t.GetMethod("EvalCode");
object s = mi.Invoke(o, null);
return s;
}
I would like to do the equivalent of:
object result = Eval("1 + 3");
string now = Eval("System.DateTime.Now().ToString()") as string
Following Biri s link, I got this snippet (modified to remove obsolete method ICodeCompiler.CreateCompiler()
:
private object Eval(string sExpression)
{
CSharpCodeProvider c = new CSharpCodeProvider();
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
StringBuilder sb = new StringBuilder("");
sb.Append("using System;\n");
sb.Append("namespace CSCodeEvaler{ \n");
sb.Append("public class CSCodeEvaler{ \n");
sb.Append("public object EvalCode(){\n");
sb.Append("return " + sExpression + "; \n");
sb.Append("} \n");
sb.Append("} \n");
sb.Append("}\n");
CompilerResults cr = c.CompileAssemblyFromSource(cp, sb.ToString());
if (cr.Errors.Count > 0)
{
throw new InvalidExpressionException(
string.Format("Error ({0}) evaluating: {1}",
cr.Errors[0].ErrorText, sExpression));
}
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");
Type t = o.GetType();
MethodInfo mi = t.GetMethod("EvalCode");
object s = mi.Invoke(o, null);
return s;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
我刚刚用纯 C# 编写了一个类似的库 (Matheval)。
它允许像 Excel 公式一样评估字符串和数字表达式。
I have just written a similar library (Matheval) in pure C#.
It allows evaluating string and number expression like excel fomular.
我们使用基于类似上述内容的系统,其中每个 C# 脚本都被编译为内存中的程序集并在单独的 AppDomain 中执行。 目前还没有缓存系统,因此脚本每次运行时都会重新编译。 我已经做了一些简单的测试,一个非常简单的“Hello World”脚本在我的机器上编译大约需要 0.7 秒,包括从磁盘加载脚本。 对于脚本系统来说 0.7 秒就足够了,但对于响应用户输入来说可能太慢,在这种情况下,像 Flee 这样的专用解析器/编译器可能会更好。
We use a system based on something like the above mentioned, where each C# script is compiled to an in-memory assembly and executed in a separate AppDomain. There's no caching system yet, so the scripts are recompiled every time they run. I've done some simple testing and a very simple "Hello World" script compiles in about 0.7 seconds on my machine, including loading the script from disk. 0.7 seconds is fine for a scripting system, but might be too slow for responding to user input, in that case a dedicated parser/compiler like Flee might be better.
看起来还有一种方法可以使用 RegEx 和 XPathNavigator 来计算表达式。 我还没有机会测试它,但我有点喜欢它,因为它不需要在运行时编译代码或使用不可用的库。
http: //www.webtips.co.in/c/evaluate-function-in-c-net-as-eval-function-in-javascript.aspx
我会尝试一下,稍后告诉它是否有效。 我也打算在Silverlight中尝试一下,但是为时已晚,我现在都快睡着了。
Looks like there is also a way of doing it using RegEx and XPathNavigator to evaluate the expression. I did not have the chance to test it yet but I kind of liked it because it did not require to compile code at runtime or use libraries that could not be available.
http://www.webtips.co.in/c/evaluate-function-in-c-net-as-eval-function-in-javascript.aspx
I'll try it and tell later if it worked. I also intend to try it in Silverlight, but it is too late and I'm almost asleep to do it now.
虽然 C# 本身不支持 Eval 方法,但我有一个 C# eval 程序,它允许评估 C# 代码。 它提供在运行时评估 C# 代码的功能,并支持许多 C# 语句。 事实上,此代码可在任何 .NET 项目中使用,但是它仅限于使用 C# 语法。 请访问我的网站 http://csharp-eval.com 了解更多详细信息。
While C# doesn't have any support for an Eval method natively, I have a C# eval program that does allow for evaluating C# code. It provides for evaluating C# code at runtime and supports many C# statements. In fact, this code is usable within any .NET project, however, it is limited to using C# syntax. Have a look at my website, http://csharp-eval.com, for additional details.
这里有一段很好的代码
https://www.c -sharpcorner.com/article/codedom-calculator-evaluating-c-sharp-math-expressions-dynamica/
下载这个并将其作为一个可以在您的项目中引用的类库。 这似乎非常快速和简单
也许这可以帮助!
There is a nice piece of code here
https://www.c-sharpcorner.com/article/codedom-calculator-evaluating-c-sharp-math-expressions-dynamica/
Download this and make it a class library which may be referenced in your project. This seems to be pretty fast and simple
Perhaps this could help !
只需使用连接字符串将算术表达式传递给 sql
您必须添加
使用 System.Data.SqlClient;
Just pass your aritmetic expression to sql using a conection string
You must add
using System.Data.SqlClient;
结果:6416.46311475
Result : 6416.46311475
我编写了一个开源项目 Dynamic Expresso,它可以将使用 C# 语法编写的文本表达式转换为委托(或表达式树)。 文本表达式会被解析并转换为表达式树,而无需使用编译或反射。
您可以这样写:
或者
我的工作基于 Scott Gu 文章 http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the- linq-dynamic-query-library.aspx 。
I have written an open source project, Dynamic Expresso, that can convert text expression written using a C# syntax into delegates (or expression tree). Text expressions are parsed and transformed into Expression Trees without using compilation or reflection.
You can write something like:
or
My work is based on Scott Gu article http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .
如果您特别想在自己的项目中调用代码和程序集,我建议使用 C# CodeDom CodeProvider。
以下是我所知道的在 C# 中动态计算字符串表达式的最流行方法的列表。
Microsoft 解决方案
非 Microsoft 解决方案(并不是说这有什么问题)
If you specifically want to call into code and assemblies in your own project I would advocate using the C# CodeDom CodeProvider.
Here is a list of the most popular approaches that I am aware of for evaluating string expressions dynamically in C#.
Microsoft Solutions
Non-Microsoft solutions (not that there is anything wrong with that)
老话题,但考虑到这是谷歌搜索时出现的第一个线程,这里是一个更新的解决方案。
您可以使用 Roslyn 的新脚本 API 来计算表达式。
如果您使用 NuGet,只需添加对 Microsoft.CodeAnalysis.CSharp 的依赖项。脚本编写。
要评估您提供的示例,很简单:
这显然没有利用脚本引擎的异步功能。
您还可以根据需要指定评估结果类型:
要评估更高级的代码片段、传递参数、提供引用、命名空间等,请检查上面链接的 wiki。
Old topic, but considering this is one of the first threads showing up when googling, here is an updated solution.
You can use Roslyn's new Scripting API to evaluate expressions.
If you are using NuGet, just add a dependency to Microsoft.CodeAnalysis.CSharp.Scripting.
To evaluate the examples you provided, it is as simple as:
This obviously does not make use of the scripting engine's async capabilities.
You can also specify the evaluated result type as you intended:
To evaluate more advanced code snippets, pass parameters, provide references, namespaces and whatnot, check the wiki linked above.