目录
前言
项目开发中有时候我们需要快速地执行一些小脚本,不想每次都去生成编译整个项目。这时如果有一个好用的动态表达式解析器那就就特别方便。
给大家推荐一个强大动态表达式解析器DynamicExpresso,它能让我们在项目中,动态执行C#脚本。本文将详细介绍DynamicExpresso的工作原理、使用方法以及它如何帮助我们提升工作效率。
通过本文的学习,我们将掌握DynamicExpresso的使用技巧,学到一项新的编程技能。
项目介绍
Dynamic Expresso 是一个用于简单 C# 语句的解释器,采用 .NET Standard 2.0 编写。Dynamic Expresso 内置了自己的解析逻辑,通过将 C# 语句转换为 .NET 的 lambda 表达式或委托来真正实现解释执行。
- 使用 Dynamic Expresso,可以创建脚本化应用程序,在不编译的情况下执行 .NET 代码,或创建动态的 LINQ 语句。
- 这个工具支持基本的算术运算,如加减乘除,以及比较和逻辑操作。它还可以进行类型测试和转换,让数据处理更加灵活。
- 可以在DynamicExpresso中声明和使用变量,包括自定义类型的实例,为复杂的数据处理提供了可能。另外,它还支持参数设置,这样就可以在多次调用同一表达式时轻松更改输入值。
- DynamicExpresso的一个显著特点是能够直接从字符串中解析出.NET委托或Lambda表达式,它能够无缝集成到你的业务逻辑中。
无论是快速原型开发还是复杂的数据处理任务,DynamicExpresso都能提供强大的支持。
项目特点
支持平台:.NET Core 3.1、.NET5.0 及以上版本、.NET 4.6.2
性能:相比其他类似项目,DynamicExpresso有较好的性能表现。
易用性:单个dll文件,无额外依赖,易于部署。
语法丰富性:支持C#的部分语法特性,如条件运算符、三元运算符、类型检查等。
项目应用
脚本化应用:创建一个环境,允许在运行时编写和执行 C# 代码片段。
条件运行:根据不同的条件动态生成并执行代码。
动态数据过滤:构建动态的 LINQ 查询,用于数据库或其他数据源的过滤和检索。
自动化工具:在自动化流程中,根据用户输入或配置文件执行特定的代码操作
项目示例
1、参数
解析的表达式可以接受一个或多个参数:
var interpreter = new Interpreter();
var parameters = new[] {
new Parameter("x", 23),
new Parameter("y", 7)
};
Assert.AreEqual(30, interpreter.Eval("x + y", parameters));
参数可以是原始类型或自定义类型。
可以一次性解析一个表达式,并多次调用它以使用不同的参数值:
var target = new Interpreter();
var parameters = new[] {
new Parameter("x", typeof(int)),
new Parameter("y", typeof(int))
};
var myFunc = target.Parse("x + y", parameters);
Assert.AreEqual(30, myFunc.Invoke(23, 7));
Assert.AreEqual(30, myFunc.Invoke(32, -2));
2、返回值
可以解析并执行无返回值的表达式(void 表达式),也可以返回任何有效的 .NET 类型。
在解析表达式时,可以指定预期的表达式返回类型。
例如,可以这样写:
var target = new Interpreter();
double result = target.Eval<double>("Math.Pow(x, y) + 5",
new Parameter("x", typeof(double), 10),
new Parameter("y", typeof(double), 2));
内置的解析器还可以理解任何给定表达式的返回类型,因此我们可以检查表达式是否返回了所期望的结果。
3、生成动态委托
可以使用 Interpreter.ParseAsDelegate< TDelegate> 方法将表达式直接解析为 .NET 委托类型,然后像普通委托一样调用。
下面的示例中,生成了一个 Func< Customer, bool> 委托,可以在 LINQ 的 where 子句中使用。
class Customer
{
public string Name { get; set; }
public int Age { get; set; }
public char Gender { get; set; }
}
[Test]
public void Linq_Where()
{
var customers = new List<Customer>
{
new Customer() { Name = "David", Age = 31, Gender = 'M' },
new Customer() { Name = "Mary", Age = 29, Gender = 'F' },
new Customer() { Name = "Jack", Age = 2, Gender = 'M' },
new Customer() { Name = "Marta", Age = 1, Gender = 'F' },
new Customer() { Name = "Moses", Age = 120, Gender = 'M' },
};
string whereExpression = "customer.Age > 18 && customer.Gender == 'F'";
var interpreter = new Interpreter();
Func<Customer, bool> dynamicWhere = interpreter.ParseAsDelegate<Func<Customer, bool>>(whereExpression, "customer");
Assert.AreEqual(1, customers.Where(dynamicWhere).Count());
}
这个是解析表达式的首选方法,当在编译时就知道表达式可以接受哪些参数以及必须返回什么值时。
4、Lambda 表达式
Dynamic Expresso 部分支持 Lambda 表达式。
例如,可以使用任何 LINQ 方法:
var x = new string[] { "this", "is", "awesome" };
var options = InterpreterOptions.Default | InterpreterOptions.LambdaExpressions; // 启用 Lambda 表达式
var target = new Interpreter(options)
.SetVariable("x", x);
var results = target.Eval<IEnumerable<string>>("x.Where(str => str.Length > 5).Select(str => str.ToUpper())");
Assert.AreEqual(new[] { "AWESOME" }, results);
注意,默认情况下解析 Lambda 表达式是禁用的,因为会带来轻微的性能开销。
要启用,必须设置 InterpreterOptions.LambdaExpressions 标志。
也可以直接从 Lambda 表达式创建一个委托:
var options = InterpreterOptions.Default | InterpreterOptions.LambdaExpressions;
// 启用 Lambda 表达式
var target = new Interpreter(options)
.SetVariable("increment", 3);
// 从 Lambda 表达式中访问一个变量
var myFunc = target.Eval<Func<int, string, string>>("(i, str) => str.ToUpper() + (i + increment)");
Assert.AreEqual("TEST8", myFunc.Invoke(5, "test"));
5、特殊标识符
this 的变量或参数可以被隐式引用。
class Customer { public string Name { get; set; } }
var target = new Interpreter();
// 'this' is treated as a special identifier and can be accessed implicitly
target.SetVariable("this", new Customer { Name = "John" });
// explicit context reference via 'this' variable
Assert.AreEqual("John", target.Eval("this.Name"));
// 'this' variable is referenced implicitly
Assert.AreEqual("John", target.Eval("Name"));
本文仅展示部分功能说明,更多功能详情可以访问源码地址进行查阅和学习。
项目地址
Github:GitHub - dynamicexpresso/DynamicExpresso: C# expressions interpreter
在线演示:Web Shell - Dynamic Expresso
最后
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!优秀是一种习惯,欢迎大家留言学习!
标签:解析器,DynamicExpresso,target,新技能,var,new,Lambda,表达式,Name From: https://blog.csdn.net/u012573563/article/details/142260613