c# - 将动作转换为 LambdaExpression
问题描述
我正在使用 NRules 并尝试从数据库加载规则。
为此,我必须使用反射来生成表达式。
public class Product
{
public string Attribute1 { get; }
public List<int> Category { get; set; }
public void AddCategory (int category){
this.Category.Add(category);
}
}
using NRules.RuleModel;
using NRules.RuleModel.Builders;
var builder = new RuleBuilder();
//some logic for buildin lefthand side
Expression<Action<IContext, Product>> action = (ctx, product) => product.AddCategory(25);
builder.RightHandSide().Action(action);
Expression<Action<IContext, Product>> action = (ctx, product) => product.AddCategory(25);
我的目标是在运行时生成“ ”。我认为这样做的唯一方法是使用反射。因为我正在从数据库中读取一些值。
我可以使用反射生成动作:
Type actionType = typeof(Action<>).MakeGenericType(new Type[] { typeof(IContext),
Type.GetType(actualModelName) });
MethodInfo eventMethodInfo = type.GetMethod("AddCategory");
Action actionFromReflection = (Action)Delegate.CreateDelegate(actionType, eventMethodInfo);
但是 NRules 方法需要一个 LambdaExpression 作为参数。
如何将“actionFromReflection”转换为 LambdaExpression?
LambdaExpression le = actionFromReflection ???
解决方案
一个委托是指真正编译的代码,而一个 Lambda 表达式是一个表达式树,接近源代码,而不是文本形式。你可以打电话给你的代表,但没有别的。从 IL 代码创建源代码将是反汇编程序的工作。
使用反射意味着“使用已经编译的东西”,这与在运行时创建它相反。所以这是错误的做法。
要在运行时创建 LambdaExpression,您可以执行类似的操作
ParameterExpression ctx = Expression.Parameter(typeof(Context), "ctx");
ParameterExpression product = Expression.Parameter(typeof(Product), "product");
LambdaExpression lambdaExpr = Expression.Lambda(
/* your actual code, depending on what you want to do */
Expression.Add(
ctx,
Expression.Constant(1)
),
new List<ParameterExpression>() { ctx, product })
实际上这个示例确实构建了 ctx => ctx +1 如果你没有返回值,你可能有一个 Expression.Call。你必须进一步调查,如何表达你想要的,作为一个表达树。这是一个广泛的话题。
您可以投射的 LambdaExpression:
var expr = (Expression<Action<ctx, product>>) lambdaExpr;
推荐阅读
- node.js - 使用 npm 时总是出现相同的类型错误
- swift - 从 macOS 上的自定义事件启动基于 SwiftUI 应用程序的项目中的窗口
- flutter - 例如,有什么方法可以让多个标签(屏幕)像在浏览器中一样进行预览?
- reactjs - 将自定义标签导入 TypeScript
- javascript - 我有个问题。当我将数据保存在 localStorage 中时,它会丢失 reduce。并向我显示内部的数据,例如 0,23,20,11 而不是统一的结果
- html - CSS:为什么这里有额外的“边距”?
- pandas - 使用内置插值方法线性外推熊猫数据框
- php - Laravel 文件系统接口 - 获取路径作为输出
- javascript - 按当前时间显示字幕
- ruby - 解析 Gemfile.lock 文件的直接和间接 Gems