微信公众号“Dotnet工控”的文章《一文看懂C#脚本》(参考文献1)介绍了基于微软的开源脚本模块Microsoft.CodeAnalysis.CSharp.Scripting从简单计算脚本到带变量运行脚本的使用方式。本文学习Microsoft.CodeAnalysis.CSharp.Scripting的基本用法并基于其实现简单的数学表达式计算功能。
之前学习过基于Flee模块计算数学表达式,Flee支持计算简单表达式、带函数的表达式、带变量的表达式,使用C#脚本可以实现类似功能。
新建Winform项目,在Nuget包管理器中搜索并安装Microsoft.CodeAnalysis.CSharp.Scripting包。
主要使用CSharpScript类并调用其中的EvaluateAsync或RunAsync函数执行C#脚本,前者运行脚本并返回结果(Run a C# script and return its resulting value),后者则仅运行脚本(Run a C# script),如须返回结果则应在脚本中设置return语句。
对于简单的四则运算表达式而言,其中仅包括数字及加减乘除符合,直接调用EvaluateAsync函数即可,示例代码及程序运行效果如下图所示:
txtResult.Text = Convert.ToString(await CSharpScript.EvaluateAsync(txtScript.Text))
计算带函数的数学表达式仅多一步操作,即在运算时引用System.Math命名空间,这样即可在数学表达式中使用Math类的所有函数。示例代码及程序运行效果如下图所示:
txtResult.Text = Convert.ToString(await CSharpScript.EvaluateAsync(txtScript.Text, ScriptOptions.Default.WithImports("System.Math")));
计算带变量的表达式与上述逻辑不同,由于涉及外部变量定义,首先需要调用CSharpScript.Create函数创建脚本对象实例,添加第一段代码及引用所需命名空间,然后调用Script.ContinueWith函数持续追加脚本代码,最后调用Script.RunAsync函数返回运行结果。示例代码及程序运行效果如下图所示:
var script = CSharpScript.Create($"int x={txtX.Text};", ScriptOptions.Default.WithImports("System.Math"));
if (!string.IsNullOrWhiteSpace(txtY.Text))
{
script = script.ContinueWith($"int y={txtY.Text};");
}
if (!string.IsNullOrWhiteSpace(txtZ.Text))
{
script = script.ContinueWith($"int z={txtZ.Text};");
}
script = script.ContinueWith(txtScript.Text);
txtResult.Text = Convert.ToString((await script.RunAsync()).ReturnValue);
参考文献:
[1]https://www.cnblogs.com/zhenl/p/15714453.html
[2]https://github.com/zhenl/CSharpScriptDemo
[3]https://github.com/dotnet/roslyn