首页 > 编程语言 >C# 新技能 DynamicExpresso 动态表达式解析器

C# 新技能 DynamicExpresso 动态表达式解析器

时间:2024-09-16 15:21:53浏览次数:15  
标签:解析器 DynamicExpresso target 新技能 var new Lambda 表达式 Name

目录

前言

项目介绍

项目特点

项目应用

项目示例

1、参数

2、返回值

3、生成动态委托

4、Lambda 表达式

5、特殊标识符

项目地址

最后


前言

项目开发中有时候我们需要快速地执行一些小脚本,不想每次都去生成编译整个项目。这时如果有一个好用的动态表达式解析器那就就特别方便。

给大家推荐一个强大动态表达式解析器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

相关文章

  • NetCore DynamicExpresso 动态表达式使用例子
    Simple.cs简单使用例子usingDynamicExpresso;namespaceDynamicExpressoDemo{classCustomer{publicstringName{get;set;}}publicclassSimple{publicstaticvoidTest(){//返回结果Interpreter......
  • Xlua解析器管理器
    usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.IO;usingUnityEngine;usingXLua;///<summary>///Lua管理器///</summary>publicclassLuaMgr:BaseManager<LuaMgr>{privateLuaEnvluaEnv;publicvoid......
  • spring 自定义属性解析器
    自定义属性解析器org.springframework.context.support.AbstractApplicationContext#prepareBeanFactorybeanFactory.setBeanClassLoader(getClassLoader());//设置EL表达式解析器(${})beanFactory.setBeanExpressionResolver(newStandardBeanExpressionResolver(beanFactory.g......
  • 数据迁移新技能,MongoDB轻松同步至ClickHouse
    在当今数据驱动的世界中,企业的成功依赖于对数据的高效管理和精准分析。数据迁移是实现这些目标的关键环节,而选择合适的工具可以让这项工作变得更加轻松和高效。ETLCloud是一款创新的ETL(提取、转换、加载)工具,它提供了简单直观的界面和强大的功能,专门为现代数据集成挑战设计。它不......
  • 数据迁移新技能,MongoDB轻松同步至ClickHouse
    在当今数据驱动的世界中,企业的成功依赖于对数据的高效管理和精准分析。数据迁移是实现这些目标的关键环节,而选择合适的工具可以让这项工作变得更加轻松和高效。ETLCloud是一款创新的ETL(提取、转换、加载)工具,它提供了简单直观的界面和强大的功能,专门为现代数据集成挑战设计。它不......
  • MySQL 源码|62 - 词法解析(V2):调用词法解析器的逻辑
    目录文档:MySQL源码|源码剖析文档目录源码位置(版本=MySQL8.0.37):sql/sql_class.cc;sql/sql_yacc.yy前置文档:MySQL源码|33-语法解析:bison基础语法规则MySQL源码|61-词法解析(V2):MySQL语法解析指定的返回值类型的联合体在sql/sql_yacc.yy中定义了%defineapi.pr......
  • 【AI大模型】LangChain框架:示例选择器与输出解析器携手,编织NLP高效精准之网
    文章目录前言一、示例选择器1.介绍及应用2.自定义示例选择器案例:AI点评姓名3.基于长度的示例选择器案例:对输入内容取反4.基于最大边际相关性(MMR)的示例选择器案例:得到输入的反义词5.基于n-gram重叠的示例选择器6.综合案例二、输出解析器1.介绍2.列表解析器3.日期......
  • NBT 解析器 Minecraft mca 文件不是 gzip 压缩文件错误
    我尝试使用NBT1.4.1模块(命名二进制标签读取器/写入器)从文件系统和.mca区域/anvil文件中使用Python读取Minecraft世界,该模块应该读取NBT格式在《我的世界》中使用。它对于level.dat等文件工作正常,但对于r.0.0.mca等区域文件会抛出错误编辑:我指的是Min......
  • 2. DRF 解析器
    目录DjangoDRF解析器1.解析器作用2.使用解析器默认配置为视图类定义解析器修改全局配置DjangoDRF解析器1.解析器作用request请求先进到APIView的dispatch方法,如果有异常走到exception。Json请求www-form请求form-data请求可以看到不同类型的请求,request.data......
  • 【JavaScript脚本宇宙】高效Web开发利器:全面解析六大HTML解析器与DOM库
    精益求精:揭秘六个改变Web开发的HTML解析与DOM操作工具前言在现代Web开发中,HTML解析器和DOM操作库是不可或缺的工具。无论是爬取数据、处理复杂的HTML文档,还是模拟浏览器环境,这些工具都扮演着关键角色。本文将深入探讨六个广泛使用的HTML解析器和DOM操作库,它们分别是:htmlpa......