AScript之eval函数详解

AScript是一个开源的C#动态脚本解析执行库,内置的eval函数可动态执行字符串脚本,在python脚本中对应的是exec函数。

一、示例

复制代码
1 Console.WriteLine(new Script().Eval("int n=10;eval(\"n+20\")")); // 30
2 Console.WriteLine(new Script().Eval("int n=10;eval(\"n+20\")", ECompileMode.All)); // 30
3 Console.WriteLine(new Script().Eval("int n=10;var s=\"n+20\";eval(s)")); // 30
4 Console.WriteLine(new Script().Eval("int n=10;var s=\"n+20\";eval(s)", ECompileMode.All)); // 20
5 Console.WriteLine(new Script().Eval("int n=10;eval(\"n+=20\");n")); // 30
6 Console.WriteLine(new Script().Eval("int n=10;eval(\"n+=20\");n", ECompileMode.All)); // 30
7 Console.WriteLine(new Script().Eval("int n=10;var s=\"n+=20\";eval(s);n")); // 30
8 Console.WriteLine(new Script().Eval("int n=10;var s=\"n+=20\";eval(s);n", ECompileMode.All)); // 10

为什么第4行输出结果是20,第8行输出结果是10呢?我们来看一下eval函数的运行机制。

二、运行机制

eval函数实际是调用Script中的Eval 方法,使用脚本中的当前编译上下文BuildContext 、数据上下文ScriptContext 和编译选项BuildOptions;

我们把当前脚本当作主干A,把eval中的脚本当作分支A1,分支A1是共享主干A中的上下文和编译选项;

1、在解析执行模式下,可以使用和修改主干A中的变量,分支A1中自定义的变量也可以传递到主干A中。

2、在编译执行模式下又有所不同,分2种场景:

1)参数为字符串常量,此时会将字符串的解析结果合并到主干A中进行编译和执行,不会产生分支A1。

2)参数为变量,由于编译期间无法确定变量的值,无法合并到主干A中进行编译,此时会产生分支A1进行单独编译执行,分支A1只能共享主干A的变量定义,无法共享赋值语句,所以分支A1中的变量n为0,且修改变量值也无法同步到主干中。

eval函数详细实现请参考源码中的AScript.Functions.EvalFunction。

三、总结

如果eval中要使用主干中的变量值,请使用解析执行模式或者参数为字符串常量。


AScript开源地址:https://gitee.com/rockey627/AScript

相关推荐
淡海水1 小时前
06-01-源码-Incremental GC总览与设计
unity·c#·gc
江沉晚呤时3 小时前
零依赖的代价与自由:我用 C# 自研了一套 Office 读写库
开发语言·c#
zimoyin5 小时前
Windows 控件获取全攻略:Win32 / UIA / MSAA + 鼠标拾取与点击关联(C# 实战)
c#·自动化
小羊没烦恼!16 小时前
铁道部新客票系统设计(二)
开发语言·前端·数据库·python·oracle·c#·php
昂好的day17 小时前
VisionMaster 通信模块实战(上):Modbus、TCP 收发、协议组装解析
开发语言·网络·网络协议·tcp/ip·c#
波力海苔夹心脆67520 小时前
C# 正则表达式零基础入门:从“看得懂“到“会用“
经验分享·后端·mysql·正则表达式·c#
昂好的day1 天前
VisionMaster(VM) 标定工具详解(上):为什么必须标定 + 九点标定手眼标定
开发语言·数码相机·c#
Elastic 中国社区官方博客1 天前
Observability:当 YAML 遇上 IConfiguration:OpenTelemetry .NET SDK 的声明式配置
大数据·开发语言·elasticsearch·搜索引擎·全文检索·.net
小羊没烦恼!1 天前
深入浅出SQL Server中的死锁
java·开发语言·前端·数据库·后端·spring·c#