c# - 将 Action 转换为 LambdaExpression

标签 c# reflection delegates action

我正在使用 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); ”。我认为唯一的方法是使用反射。因为我正在从数据库中读取一些值。

我可以使用反射生成 Action :

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  ???

最佳答案

委托(delegate)指的是真正的编译代码,而 Lambda 表达式是一个表达式树,接近源代码,只是不是文本形式。你可以调用你的委托(delegate),但别无他法。从 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;

关于c# - 将 Action 转换为 LambdaExpression,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58975116/

相关文章:

c# - 单元测试 WCF REST 服务

c# - WebHost.CreateDefaultBuilder(string [] args) 可能的命令行参数是什么?

c++ - C++ 中的轻量级反射

java - 如何在 Java 中获取方法的所有可能调用者 - 如调用层次结构

iphone - 发送到实例 0x6d79ed0 的无法识别的选择器

c# - 委托(delegate)操作 : new Action or casting Action?

arrays - Array.Sort(array, Comparison<t>) 如何执行?

javascript - 单击按钮时从主页中删除元素

c# - 通过反射动态继承内部类

c# - 使用参数的 npgsql 语句