AScript 1.4.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package AScript --version 1.4.1
                    
NuGet\Install-Package AScript -Version 1.4.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AScript" Version="1.4.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AScript" Version="1.4.1" />
                    
Directory.Packages.props
<PackageReference Include="AScript" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AScript --version 1.4.1
                    
#r "nuget: AScript, 1.4.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AScript@1.4.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AScript&version=1.4.1
                    
Install as a Cake Addin
#tool nuget:?package=AScript&version=1.4.1
                    
Install as a Cake Tool

AScript

相关文章

介绍

C#动态脚本解析编译执行引擎

  • 支持注入变量
  • 支持定义变量
  • 支持注入函数
  • 支持定义函数
  • 支持注入类型
  • 支持LINQ语法、Lambda表达式
  • 支持元组类型、匿名类型、动态类型
  • 支持事件处理
  • 支持异步
  • 支持16进制整数表示:0x0A
  • 支持多语句:用分号分隔多条语句
  • 支持行注释:// 行注释
  • 支持块注释:/* 块注释 */
  • 支持if/else语句
  • 支持for/while/foreach语句
  • 支持continue/break/return
  • 支持throw语句
  • 支持try-catch-finally语句
  • 支持自定义语法解析(自定义关键字)
  • 支持流式读取表达式
  • 支持自定义脚本语言,已实现CSharp/Python3/SQL/JavaScript四种语言
  • 支持2种执行模式:
  1. 解析执行:解析过程中计算结果,对于非循环语句有较高的性能及低内存,有循环语句则建议使用第2种编译执行方式
var script = new Script();
var result = script.Eval("5+8*6");
Assert.AreEqual(53, result);
  1. 编译执行:解析过程中构建Expression表达式树,编译结果可缓存,对于执行频率高的表达式建议使用编译缓存方式执行,提高性能
// 方式1
var script = new Script();
var result = script.Eval("5+8*6", ECompileMode.All);
// 方式2
var script = new Script();
script.Options.CompileMode = ECompileMode.All;
var result = script.Eval("5+8*6");
// 方式3(缓存)
var script = new Script();
// -1表示缓存时间为永久缓存
var result = script.Eval("5+8*6", -1);
  • 上下文环境会缓存临时变量及函数,编译执行模式可关闭该缓存(获得更高的性能)
var script = new Script();
script.Options.CompileMode = ECompileMode.All;
//script.Options.RewriteVariables = false;
//script.Options.RewriteFunctions = false;
script.Eval("int sum(int a, int b)=>a+b;int n=10;sum(n,5)");
script.Eval("n+6"); // 如果RewriteVariables为false,则抛异常变量n不存在
script.Eval("sum(10,20)"); // 如果RewriteFunctions为false,则抛异常函数sum不存在
var sum = script.Context.GetFunc<int, int, int>("sum");
int result = sum(10, 20);

安装

install-package AScript

使用说明

  • 命名空间:using AScript;
  • 已内置C#常用数据类型:int/bool/string/long/double/DateTime等
  • 已内置Convert数据转换方法:'12'.ToInt32()等同于ToInt32('12')或者Convert.ToInt32('12')
  • 已内置Enumerable扩展方法:list.Where(a=>xxx).Select(a=>new { xxx })
  • 已内置Queryable扩展方法:query.Where(a=>xxx).Select(a=>new { xxx })
注入类型及类型中的方法
var script = new Script();
script.Context.AddType<Person>();
script.Eval("var p1 = new Person('tom', 20); p1.SayHello()"); // Hello, my name is tom, I'm 20 years old
script.Eval("var p2 = Person.Create('john', 35); p2.SayHello()"); // Hello, my name is john, I'm 35 years old

// 添加类中的所有公开静态方法
script.Context.AddFunc<Person>();
script.Eval("var p3 = Create('jim', 15); p3.SayHello()"); // Hello, my name is jim, I'm 15 years old
// 添加类中的所有公开实例方法
var p = new Person("san", 27);
script.Context.AddFunc(p);
script.Eval("SayHello()"); // Hello, my name is san, I'm 27 years old

public class Person
{
	public string Name { get; set; }
	public int Age { get; set; }

	public event EventHandler<EventArgs> Saying;

	public Person() { }
	public Person(string name, int age)
	{
		this.Name = name;
		this.Age = age;
	}
	
	protected virtual void OnSaying(EventArgs e)
	{
		this.Saying?.Invoke(this, e);
	}

	public string SayHello()
	{
		OnSaying(EventArgs.Empty);
		return $"Hello, my name is {this.Name}, I'm {this.Age} years old";
	}

	public static Person Create(string name, int age)
	{
		return new Person(name, age);
	}
}
变量
var script = new Script();
script.Context.SetVar("m", 6);
var result = script.Eval("int n=8;n+m+10*(3+0x0A)");
Assert.AreEqual(8 + 6 + 10 * (3 + 0x0A), result);
匿名类型
string s = @"
var a = new { Name='tony', Age=20 }
a.Name + ':' + a.Age
";
var script = new Script();
Assert.AreEqual("tony:20", script.Eval(s));
var a = script.Eval("a");
// 获取脚本中定义的匿名类型
var type = Script.AnonymousTypes.CreateType(new[] { "Name", "Age" }, new[] { typeof(string), typeof(int) });
Assert.IsInstanceOfType(a, type);
dynamic d = a;
Assert.AreEqual("tony", d.Name);
Assert.AreEqual(20, d.Age);
Assert.AreEqual("{ Name = tony, Age = 20 }", a.ToString());
动态类型
string s = @"
var a = new ExpandoObject();
a.Name = 'jim';
a.Age = 23;
a
";
var script = new Script();
dynamic a = script.Eval(s);
Assert.IsInstanceOfType(a, typeof(ExpandoObject));
Assert.AreEqual("jim", a.Name);
Assert.AreEqual(23, a.Age);
类型转换
string s = "int n = 10; n+(long)n";
var script = new Script();
var r = script.Eval(s, out var type);
Assert.AreEqual(20L, r);
Assert.AreEqual(typeof(long), type);
注入函数
var script = new Script();
script.Context.AddFunc<int, int, int>("sum", (a, b) => a + b);
script.Context.AddFunc<int, int, int, int>("sum", (a, b, c) => a + b + c);
script.Context.AddFunc<int, int, int>("mult", (a, b) => a * b);
Assert.AreEqual(1+2+8+1+2+3+5*6, script.Eval("sum(1,2)+8+sum(1,2,3)+mult(5,6)"));
自定义函数
string s = @"
int exec(int a, int b) {
	var n=mult(a,10);
	n+b;
}
// 2个数相加
int sum(int a, int b)=>a+b;
// 3个数相加
int sum(int a, int b, int c)=>a+b+c;
// 乘法
int mult(int a, int b)=>a*b;
/* 
调用函数计算结果:
1 + 2 + 8 + 1 + 2 + 3 + 5 * 6
*/
sum(1,2)+8+sum(1,2,3)+mult(5,6)
";
var script = new Script();
var result = script.Eval(s);
Assert.AreEqual(1 + 2 + 8 + 1 + 2 + 3 + 5 * 6, result);
Assert.AreEqual(1 + 2 + 8, script.Eval("sum(1,2)+8"));
Assert.AreEqual(5 * 10 + 2 + 8, script.Eval("exec(5,2)+8"));
递归
string s = @"
int exec(int a) {
	if (a < 1) return 0;
	a + exec(a-1);
}
exec(5)
";
var script = new Script();
Assert.AreEqual(15, script.Eval(s));
Assert.AreEqual(55, script.Eval("exec(10)"));
事件

示例1:

var s = @"
var p = new Person('tom', 20);
p.Saying += (ss,ee)=>{
	(ss as Person).Age+=1;
}
p.SayHello();
p.SayHello();
";
var script = new Script();
script.Context.AddType<Person>();
Assert.AreEqual("Hello, my name is tom, I'm 22 years old", script.Eval(s));

示例2:

var s = @"
void saying(object sender, EventArgs e) {
	(sender as Person).Age+=1;
}
var p = new Person('tom', 20);
p.Saying += saying;
p.SayHello();
p.Saying -= saying;
p.SayHello();
";
var script = new Script();
script.Context.AddType<Person>();
Assert.AreEqual("Hello, my name is tom, I'm 21 years old", script.Eval(s));

示例3:

var s = @"
void saying(object sender, EventArgs e) {
	(sender as Person).Age+=1;
}
var p = new Person('tom', 20);
p.Saying += saying;
p.SayHello();
p.SayHello();
";
var script = new Script();
script.Context.AddType<Person>();
Assert.AreEqual("Hello, my name is tom, I'm 22 years old", script.Eval(s));
var p = script.Eval<Person>("p");
Assert.AreEqual("Hello, my name is tom, I'm 23 years old", p.SayHello());
var handle = script.Context.GetEvent<EventHandler<EventArgs>>("saying");
p.Saying -= handle;
Assert.AreEqual("Hello, my name is tom, I'm 23 years old", p.SayHello());
字符串插值
string s = "var name='tom'; $'hello {name}, 5+8={5+8}'";
var script = new Script();
Assert.AreEqual("hello tom, 5+8=13", script.Eval(s));
字符串索引和截取
var script = new Script();
Assert.AreEqual('e', script.Eval("'hello'[1]"));
Assert.AreEqual('e', script.Eval("'hello'[-4]"));
Assert.AreEqual("ell", script.Eval("'hello'[1:4]"));
Assert.AreEqual("ell", script.Eval("'hello'[-4:-1]"));
数组
var arr = new [] { 1, 2, 3};
var arr = new int[] { 1, 2, 3 };
arr.Length;
arr[0];
列表
var script = new Script();
var result1 = (List<int>)script.Eval("var list1 = [0,1,2,3,4]; list1[1:4]");
var result2 = (List<int>)script.Eval("var list2 = new List<int> { 0,1,2,3,4 }; list2[-4:-1]");
CollectionAssert.AreEqual(new List<int> { 1, 2, 3 }, result1);
CollectionAssert.AreEqual(new List<int> { 1, 2, 3 }, result2);
Assert.AreEqual(1, script.Eval("list1[1]"));
Assert.AreEqual(1, script.Eval("list1[-4]"));
点操作符
var script = new Script();
Assert.AreEqual(DateTime.Now.Year, script.Eval("DateTime.Now.Year"));
Assert.AreEqual(int.MaxValue, script.Eval("int.MaxValue"));
Assert.AreEqual("hello".Length, script.Eval("'hello'.Length"));
Assert.AreEqual("hello".Substring(1, 2), script.Eval("'hello'.Substring(1, 2)"));
for
string s = @"
int total=0;
for(var i=1; i<=10; i++) {
	total += i;
}
total";
var script = new Script();
Assert.AreEqual(55, script.Eval(s));
foreach
string s = @"
int n=0;
var list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
foreach(var item in list)
{
	if (item % 2 == 0) continue;
	if (item >10) break;
	n+=item;
}
n";

var script = new Script();
Assert.AreEqual(25, script.Eval(s));
// 编译缓存方式执行
Assert.AreEqual(25, script.Eval(s, -1));
while
string s = @"
int total=0;
int n = 1;
while(n <= 10) {
	total += n;
	n++;
}
total";
var script = new Script();
Assert.AreEqual(55, script.Eval(s));
case when

与C#中的switch语法不同,语句块中不需要break,并且整体语句返回对应when或default语句的值。

var s = @"
var n=1;
case(n) {
when 0:
when 1:
	int m=6;
	m+4;
when 2: 20;
default:
	int m=9
	m+21;
}
";
var script = new Script();
Assert.AreEqual(10, script.Eval(s));
异常处理
string s = @"
int n=0;
try {
	throw new FormatException('error');
} catch(ArgumentException) {
	n=1;
} catch(FormatException) {
	n=2;
} catch(Exception) {
	n=10;
} finally {
	n+=100
}
n;
";
var script = new Script();
Assert.AreEqual(102, script.Eval(s));
LINQ
  • group
string s = @"
var persons = new[] { new Person(""tom"", 20), new Person(""jim"", 25), new Person(""san"", 18), new Person(""kit"", 25) }.AsQueryable();
var q = from a in persons
		group a by a.Age into g
		select new { g.Key, Count = g.Count() };
q.ToList()
";
var script = new Script();
script.Context.AddType<Person>();
var list = script.Eval<IList>(s);
Assert.AreEqual(3, list.Count);
dynamic d0 = list[0];
Assert.AreEqual(20, d0.Key);
Assert.AreEqual(1, d0.Count);
dynamic d1 = list[1];
Assert.AreEqual(25, d1.Key);
Assert.AreEqual(2, d1.Count);
dynamic d2 = list[2];
Assert.AreEqual(18, d2.Key);
Assert.AreEqual(1, d2.Count);
  • join
from p in persons
join a in addresses on p.Id equals a.UserId
where p.Age > 20
  • left join(AScript定制语法)
// 写法1
from p in persons
join a in addresses on p.Id equals a.UserId into aa
from a in aa.DefaultIfEmpty()
// 写法2
from p in persons
left join a in addresses on p.Id equals a.UserId
  • right join(AScript定制语法)
from p in persons
right join a in addresses on p.Id equals a.UserId

实际会转换为left join:

from a in addresses
left join p in persons on a.UserId equals p.Id
  • orderby asc/desc为AScript定制语法,也支持C#标准语法ascending/descending
from p in persons
orderby p.Age desc
Queryable扩展方法

Queryable中的扩展方法,包含Where/Select/OrderBy/Skip/Take/FirstOrDefault/SelectMany/Join等等。 注:.NET10新增了LeftJoin/RightJoin扩展方法

string s = @"
var q = [1,2,3,4,5].AsQueryable();
var r = q.Where(a=>a%2==0).ToList();
";
var script = new Script();
var r = script.Eval(s);
Assert.IsInstanceOfType(r, typeof(List<int>));
Assert.AreEqual("2,4", string.Join(',', (List<int>)r));
Enumerable扩展方法

Enumerable中的扩展方法,包含Where/Select/OrderBy/Skip/Take/FirstOrDefault/SelectMany/Join等等。

string s = @"
var r = [1,2,3,4,5].Where(a=>a%2==0).ToList();
";
var script = new Script();
var r = script.Eval(s);
Assert.IsInstanceOfType(r, typeof(List<int>));
Assert.AreEqual("2,4", string.Join(',', (List<int>)r));
static语句

static语句是在编译期间进行解析执行,即static语句不参与编译,而是直接执行结果。 注意:static语句中使用的变量也必须在static语句中定义的,否则报错变量不存在。

var s = @"
static int n = 10; // 直接执行,不参与编译
static x = n * 2; // 直接执行,不参与编译
int y = static n * 2; // 编译结果:y = 20
/*
int m=20;
int a = static m * 2; // 报错:variable m is not exists
*/
int z = n * 2; // 编译结果:z = n * 2
x+y+z;
";
var script = new Script();
// 编译
var func = script.Compile<int>(s);
Assert.AreEqual(10, script.Context.EvalVar("n"));
Assert.AreEqual(20, script.Context.EvalVar("x"));
Assert.IsNull(script.Context.EvalVar("y"));
Assert.IsNull(script.Context.EvalVar("z"));
// 执行
Assert.AreEqual(60, func());
自定义语法解析
  • 注:自定义语法解析需要谨慎处理,否则会破坏后续语法解析,导致脚本执行异常或者执行结果不符合预期。
string s = @"
int n=0;
var list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
foreach(var item in list)
{
	if (item % 2 == 0) 继续;
	if (item >10) 中断;
	n+=item;
}
n";

var script = new Script();
script.Context.AddTokenHandler("继续", ContinueTokenHandler.Instance);
script.Context.AddTokenHandler("中断", BreakTokenHandler.Instance);
Assert.AreEqual(25, script.Eval(s));
多脚本语言

脚本中使用@lang/@end语法嵌入其他语言,如果没有@end,则表示后面的脚本都指定该语言执行。

string s = @"
int n=10;
@lang python3
def sum(a,b):
	return a+b
@end
@lang sql
declare m int;
set m=20;
@end
sum(m, n)";
var script = new Script();
Assert.AreEqual(30, script.Eval(s));
编译
var script = new Script();
//var func = script.Compile<int, int, int>("a+b*2", "a", "b");
var func = script.Compile<Func<int, int, int>>("a+b*2", new[] { "a", "b" });
Assert.IsNotNull(func);
Assert.AreEqual(11, func(3, 4));
Lambda

脚本生成Lambda表达式,应用场景:脚本->LINQ

var script = new Script();
var whereCondition = script.Lambda<Person, bool>("p.Name=='tom' || p.Name=='jim'", "p");
IQueryable<Person> query = ...;
var list = query.Where(whereCondition).ToList();
异步和await
Func<int, int, Task<int>> sum = async (a, b) =>
{
	await Task.Delay(1000);
	return a + b;
};
var script = new Script();
script.Context.AddFunc("sum", sum);
// 方式一:EvalAsync异步执行await脚本,传递async/await到脚本
var result = await script.EvalAsync("await sum(5, 10)");
Assert.AreEqual(15, result.Value);
Assert.AreEqual(typeof(int), result.Type);
// 方式二:Eval同步执行await脚本,脚本实际调用Task.Wait() + Task<T>.Result
var result = script.Eval("await sum(5, 10)", out var type);
Assert.AreEqual(15, result);
Assert.AreEqual(typeof(int), type);
// 超时取消
var cts = new CancellationTokenSource(100);
await Assert.ThrowsExceptionAsync<OperationCanceledException>(async () =>
{
	await script.EvalAsync("(await sum(5, 10)) + 5", cancellationToken: cts.Token);
});
// @@CancellationToken关键字:异步执行值为参数中的cts.Token,同步执行值为CancellationToken.None
await Assert.ThrowsExceptionAsync<TaskCanceledException>(async () =>
{
	await script.EvalAsync("await Task.Delay(1000, @@CancellationToken)", cancellationToken: cts.Token);
});
扩展构造函数

方法名格式:new_{类型名称}_

string s = @"
// 脚本中扩展构造函数
Person new_Person(string firstName, string lastName) {
	var name = firstName + lastName;
	return new Person { Name = name };
}
// 调用脚本中扩展的构造函数
var p1 = new Person('张', '三');
// 调用外部扩展的构造函数
var p2 = new Person('李四');
";
var script = new Script();
script.Context.AddType<Person>();
script.Context.AddFunc<string, Person>("new_Person", name => new Person { Name = name });
script.Eval(s);
var p1 = script.Eval<Person>("p1");
var p2 = script.Eval<Person>("p2");
Assert.AreEqual("张三", p1.Name);
Assert.AreEqual("李四", p2.Name);
扩展静态方法

方法名格式:{类型名称}_{方法名}

string s = @"
// 脚本中扩展静态方法
Person Person_Create(string firstName, string lastName) {
	var name = firstName + lastName;
	return new Person { Name = name };
}
// 调用脚本中扩展的静态方法
var p1 = Person.Create('张', '三');
// 调用外部扩展的静态方法
var p2 = Person.Create('李四');
";
var script = new Script();
script.Context.AddType<Person>();
script.Context.AddFunc<string, Person>("Person_Create", name => new Person { Name = name });
script.Eval(s);
var p1 = script.Eval<Person>("p1");
var p2 = script.Eval<Person>("p2");
Assert.AreEqual("张三", p1.Name);
Assert.AreEqual("李四", p2.Name);
扩展实例方法

方法第1个参数为要扩展的实例类型参数

string s = @"
// 脚本中扩展实例方法
string SayHi(Person p, string yourName) {
	var hi = $'hi {yourName}, my name is {p.Name}';
	return hi;
}
var p = new Person('tom', 20);
// 调用脚本中扩展的实例方法
var hi = p.SayHi('john');
// 调用外部扩展的实例方法
var night = p.SayGoodNight('john');
";
var script = new Script();
script.Context.AddType<Person>();
script.Context.AddFunc<Person, string, string>("SayGoodNight", (p, yourName) => $"good night {yourName}, my name is {p.Name}");
script.Eval(s);
var hi = script.Eval<string>("hi");
var night = script.Eval<string>("night");
Assert.AreEqual("hi john, my name is tom", hi);
Assert.AreEqual("good night john, my name is tom", night);
扩展静态属性

暂只支持扩展读属性,方法名格式:{类名}get{属性名}

string s = @"
// 脚本中扩展静态属性
string Person_get_DefaultName() {
	return 'ABC';
}
Person.DefaultName;
";
var script = new Script();
script.Context.AddType<Person>();
Assert.AreEqual("ABC", script.Eval(s));
扩展实例属性

暂只支持扩展读属性,方法第1个参数为该类型参数,方法名格式:get_{属性名}

string s = @"
// 脚本中扩展实例属性
string get_FullInfo(Person p) {
	var info = $'name:{p.Name},age:{p.Age}';
	return info;
}
var p = new Person('tom', 20);
// 调用脚本中扩展的实例属性
var fullInfo = p.FullInfo;
";
var script = new Script();
script.Context.AddType<Person>();
Assert.AreEqual("name:tom,age:20", script.Eval(s));
脚本模块

接口IScriptModule定义脚本模块,集中管理变量、方法、类型等,这在自定义其他脚本语言时非常有用,比如js语言。

  • 定义扩展PersonExtensions
public static class PersonExtensions
{
	// 扩展构造函数
	public static Person new_Person(string firstName, string lastName)
	{
		return new Person { Name = firstName + lastName, Age = 18 };
	}

	// 扩展静态方法
	public static Person Person_Create(string firstName, string lastName)
	{
		var name = firstName + lastName;
		return new Person { Name = name, Age = 18 };
	}

	// 扩展静态属性
	public static string Person_get_DefaultName()
	{
		return "ABC";
	}

	// 扩展实例属性
	public static string get_FullInfo(Person p)
	{
		return $"name:{p.Name},age:{p.Age}";
	}

	// 扩展实例方法
	public static string SayHi(Person p, string yourName)
	{
		return $"hi {yourName}, my name is {p.Name}";
	}
}
  • 定义模块PersonModule
public class PersonModule : IScriptModule
{
	public object Install(BaseContext context)
	{
		context.AddType<Person>();
		context.AddFunc(typeof(PersonExtensions));
		return null;
	}

	public void Uninstall(BaseContext context)
	{
	}
}
  • 向上下文或指定语言安装模块
// 当前上下文中安装模块
var script = new Script();
script.Context.InstallModule(new PersonModule());
// 或者指定语言安装模块
// CSharpLang.Instance.InstallModule(new PersonModule());
  • 脚本中调用扩展
string s = @"
var p1 = new Person('张', '三');
var p2 = Person.Create('李', '四');
var hi = p1.SayHi(Person.DefaultName);
var info = p2.FullInfo;
";
script.Eval(s);
var hi = script.Eval("hi");
var info = script.Eval("info");
Assert.AreEqual("hi ABC, my name is 张三", hi);
Assert.AreEqual("name:李四,age:18", info);
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net45 is compatible.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on AScript:

Package Downloads
AScript.Lang.Sql

基于AScript扩展的SQL脚本语言; 快速开始: // 添加sql脚本语言 Script.Langs.Set("sql", SqlLang.Instance); string s = @" @lang sql select name,age from list where name like 'to%' and age=10 "; var script = new Script(); script.Context.SetVar("list", new [] { new Person("tommy", 15), new Person("tony", 10) }); var list = script.Eval<IEnumerable<dynamic>>(s).ToList(); Assert.AreEqual(1, list.Count); Assert.AreEqual("tony", list[0].name); Assert.AreEqual(10, list[0].age);

AScript.Lang.JavaScript

基于AScript扩展的JavaScript脚本语言,支持js基础语法及数据类型; 快速开始: // 注册js脚本语言 Script.Langs.Set("js", JavaScriptLang.Instance); // 执行js脚本 string s = @" @lang js function sum(a, b) { return a+b; } var n=10; sum(n,5) "; var script = new Script(); // 上下文中指定语言,或者脚本中使用@lang指定语言 //script.Context.Langs = new [] { "js" }; var result = script.Eval(s); Assert.AreEqual(15L, result);

AScript.Lang.JavaScript.axios

js axios模块; 快速开始: // 注册js脚本语言 Script.Langs.Set("js", JavaScriptLang.Instance); // 语言环境中注册axios模块 JavaScriptLang.Instance.AddModule("axios", new JavaScriptAxiosModule()); // 引入axios并调用相关方法 string s = @" var axios = require('axios'); axios.get('https://www.runoob.com/try/ajax/json_demo.json') .then(res=>{ console.log('result', res); }) .catch(error=> { console.log(error); }); "; var script = new Script(); script.Context.Langs = new [] { "js" }; // 或者在当前上下文环境中注册axios模块 //script.Context.AddModule("axios", new JavaScriptAxiosModule()); script.Eval(s);

AScript.Lang.Python3

基于AScript扩展的python3脚本语言,支持python3基础语法及数据类型; 快速开始: // 注册Python3脚本语言 Script.Langs.Set("python3", Python3Lang.Instance); // 执行python3脚本 string s = @" @lang python3 def sum(a, b) : return a+b; n=10 sum(n,5) "; var script = new Script(); // 上下文中指定语言,或者脚本中使用@lang指定语言 //script.Context.Langs = new [] { "python3" }; var result = script.Eval(s); Assert.AreEqual(15L, result);

AScript.Lang.JavaScript.fs

js fs模块; 快速开始: // 注册js脚本语言 Script.Langs.Set("js", JavaScriptLang.Instance); // 语言环境中注册fs模块 JavaScriptLang.Instance.AddModule("fs", new JavaScriptFileSystemModule()); // 引入fs并调用相关方法 string s = @" var fs = require('fs'); fs.writeFileSync('test.txt', 'hello world', 'utf-8'); fs.readFileSync('test.txt', 'utf-8'); "; var script = new Script(); script.Context.Langs = new [] { "js" }; // 或者在当前上下文环境中注册fs模块 //script.Context.AddModule("fs", new JavaScriptFileSystemModule()); var result = script.Eval(s); Assert.AreEqual("hello world", result);

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.7.2 99 9/5/2026
1.7.1 134 9/4/2026
1.7.0 324 8/26/2026
1.6.0 345 8/18/2026
1.5.0.2 119 8/13/2026
1.5.0.1 108 8/12/2026
1.5.0 338 8/12/2026
1.4.1 209 7/16/2026
1.4.0 330 7/14/2026
1.3.1 224 6/8/2026
1.3.0 161 6/7/2026
1.2.7 133 5/26/2026
1.2.6 134 5/21/2026
1.2.5 119 5/20/2026
1.2.4 121 5/17/2026
1.2.3 116 5/15/2026
1.2.2 120 5/13/2026
1.2.1 122 5/11/2026
1.2.0.1 124 5/10/2026
1.2.0 114 5/10/2026
Loading failed

优化?:/OrElse/AndAlso/if/while语句的条件判断,支持object判断;修复return语句在编译模式下的bug