C#常用三方库使用心得

三方库

RulesEngine

rule字段

字段 用途 场景示例
RuleName 规则标识 "HighTemperatureWarning"
Expression 判断条件 telemetry.Temperature > 40
SuccessEvent 成功时返回 "TEMP_WARNING"
ErrorMessage 失败信息 "传感器读数异常"
Actions 后置动作 启动空调、发送短信
LocalParams 中间变量 计算变化率、平均值

lambda表达式

语法上就是动态LINQ。

表达式传参:

c# 复制代码
ruleDefinitions.Add(new Rule
{
    RuleName = "rule1",
    Expression = "$v > $threshold",
    ErrorMessage = "Value must be less than $threshold",
    SuccessEvent = "error"
});

// 准备输入数据
RuleParameter[] input = [new("$v", 50), new("$threshold", 40)];

// 执行规则检查
var results = await rulesEngine.ExecuteAllRulesAsync("AlarmRules", input);

RuleEngine编译规则表达式的关键逻辑在namespace RulesEngine.ExpressionBuilders的RuleExpressionParser.cs的Parse函数里:

c# 复制代码
public Expression Parse(string expression, ParameterExpression[] parameters, Type returnType)
  {
    ParsingConfig parsingConfig = new ParsingConfig()
    {
      CustomTypeProvider = (IDynamicLinqCustomTypeProvider) new CustomTypeProvider(this._reSettings.CustomTypes),
      IsCaseSensitive = this._reSettings.IsExpressionCaseSensitive
    };
    try
    {
      // 这个ExpressionParser就是System.Linq.Dynamic.Core库里解析动态LINQ的解析器
      return new ExpressionParser(parameters, expression, Array.Empty<object>(), parsingConfig).Parse(returnType);
    }
    catch (ParseException ex)...

规则表达式的校验

规则表达式实际上是一个动态LINQ,可使用System.Linq.Dynamic.Core库的DynamicExpressionParser.ParseLambda来校验,该函数最终也会调用ExpressionParser.Parse来解析规则字符串:

c# 复制代码
public static LambdaExpression ParseLambda(
    Type? delegateType,
    ParsingConfig? parsingConfig,
    bool createParameterCtor,
    ParameterExpression[] parameters,
    Type? resultType,
    string expression,
    params object?[]? values)
  {
    ...
    ExpressionParser expressionParser = new ExpressionParser(parameters, expression, values, parsingConfig);
    Expression expression1 = expressionParser.Parse(resultType, createParameterCtor);
    //如果是lambda表达式,则返回
    if (expression1 is LambdaExpression lambda)
      return lambda;
    if (parsingConfig != null && parsingConfig.RenameParameterExpression && parameters.Length == 1)
    {
      ParameterExpression parameterExpression;
      Expression body = new ParameterExpressionRenamer(expressionParser.LastLambdaItName).Rename(expression1, out parameterExpression);
      return !(delegateType == (Type) null) ? Expression.Lambda(delegateType, body, parameterExpression) : Expression.Lambda(body, parameterExpression);
    }
    // 如果不是,构造一个lambda表达式返回
    return !(delegateType == (Type) null) ? Expression.Lambda(delegateType, expression1, parameters) : Expression.Lambda(expression1, parameters);
  }

lambda表达式与C#语法的差异

基本上与C#语法是类似的,但由于动态LINQ是单独解析的(而不是用C#的Roslyn编译器),所以还是有些区别,目前发现的:

  • double类型也能进行位操作,而这一点在C#里编译都不过,原因是动态LINQ会自动把double截断为整型。
  • 类型转换用int(v),而不像C#里那样(int)v

IMemoryCache组件

过期策略

策略类型 说明 适用场景
绝对过期 固定时间点过期 数据在特定时间后失效(如整点更新)
相对过期 从缓存写入开始计时 数据在一段时间后失效
滑动过期 每次访问重置计时器 热点数据,长时间不访问则清除
组合策略 绝对+滑动同时使用 保证最终过期 + 活跃续期
优先级 内存压力时优先清除 缓存驱逐时的权重控制

全局性

IMemoryCache是ASP.NET里的singleton服务,相当于一个全局字典,因此字典key的选择必须带上业务或租户隔离字段。

相关推荐
djarmy5 小时前
MAIN.c(1): warning C318: can’t open file ‘STC8G.H’ 报错 解决 分析
c语言·开发语言·mongodb
HEJOO96 小时前
深入理解 Java volatile 关键字:原理、用法与常见误区
java·开发语言·spring
曹牧6 小时前
Java:no content to map due to end of input
java·开发语言
梦梦代码精6 小时前
《回收租赁系统技术选型避坑指南:业务闭环与二开自由度详解》
开发语言·低代码·docker·开源·代码规范
隔窗听雨眠6 小时前
记一次SQL Server数据库性能分析:从CPU100%到单配置修复的完整诊断
开发语言·数据库·php
David猪大卫6 小时前
【C++修炼】智能指针使用及原理
开发语言·c++·经验分享·笔记·学习·考研·面试
charlie1145141916 小时前
现代Qt开发之图像处理进阶:像素操作与格式转换
开发语言·图像处理·qt
李永奉6 小时前
中科蓝讯SDK开发-BT893x 面条耳机连接vivo手机后连接APP端,最后手机端设置页面手动断开蓝牙连接,此时耳机端假断开
c语言·开发语言·嵌入式硬件·物联网·智能手机·电脑
秦老师Q7 小时前
php零基础入门到实战,从语法到框架,一篇搞定
开发语言·php
驭渊的小故事8 小时前
多线程02
java·开发语言·jvm