构建表达式时,如何避免返回整数。 [英] When building an expression how do I avoid having to return an integer.

查看:52
本文介绍了构建表达式时,如何避免返回整数。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用一些反射元素和System.Linq.Expressions命名空间构建规则引擎。我试图以

Expression.Lambda< Func< T,int>>(expressionToCompile,参数).Compile();

的形式构建一个Lamdba表达式

这迫使我从编译表达式中返回一个整数 - 我试过从函数定义中删除int,这导致了我更多的问题。



我尝试了什么:



在我的代码中,我的代码包含以下方法:



I am trying to build a rules engine using some elements of reflection and the System.Linq.Expressions namespace. I am trying to build a Lamdba expression in the form of
Expression.Lambda<Func<T, int>>(expressionToCompile, parameter).Compile();

Which is forcing me to return an integer out the compiled expression - I have tried removing the int from the function definition and this has caused me more issues.

What I have tried:

At the momment my code contains the following method:

private static void CompileRuleDefinition<T>(RuleDefinition<T> ruleDefinition)
        {
            var parameter = Expression.Parameter(typeof(T));
            Expression expresion = BuildCompoundConditions(ruleDefinition, parameter);
            Expression expressionToCompile = null;
            Expression thenClause = BuildAssignExpression<T>(parameter, ruleDefinition.ThenAction);

            if (expresion != null)
            {
                if (ruleDefinition.ThenAction != null && ruleDefinition.ElseAction == null)
                {
                    expressionToCompile =
                        Expression.Block(
                            Expression.IfThen(
                                expresion,
                                thenClause),
                            Expression.Constant(42));
                }

                if (ruleDefinition.ThenAction != null && ruleDefinition.ElseAction != null)
                {
                    Expression elseClause = BuildAssignExpression<T>(parameter, ruleDefinition.ElseAction);
                    expressionToCompile =
                        Expression.Block(
                            Expression.IfThenElse(
                                expresion,
                                thenClause,
                                elseClause),
                            Expression.Constant(42));
                }

                if (expressionToCompile != null)
                {
                    ruleDefinition.CompiledExpression =
                        Expression.Lambda<Func<T, int>>(expressionToCompile, parameter).Compile();
                }
            }
        }





我不喜欢使用命令:



I do not like the use of the command :

Expression.Constant(42));

这在我的代码中没有任何作用,只是允许返回整数。 Then Clause和Else Clause返回的类型可以从Void(这是我的问题开始的地方,因为动作可能是在类< t>上调用void方法)到int,bool等等



我正在寻找的是一个解决方案,我不需要这个冗余代码。



(是的,如果ThenAction也是NULL,代码确实有问题)

this does nothing in my code but simply allows the integer to be returned. The types returned by the "Then Clause" and the "Else Clause" can varying from being "Void" (which was where my problem started as the action could be to call a void method on class <t>) through int, bool etc.

What I am looking for is a solution in which I don't have to have this piece of redundant code.

(yes the code does have an issue if the ThenAction is also NULL)

推荐答案

我收到了一个使用Action而不是Func的建议(出于某种原因,这种反应没有出现)。我已经应用了更改并且所有测试都成功 - 看起来像是一个修复程序。非常感谢。





I have recieved a suggestion to use Action instead of Func (for some reason this response does not appear). I have applied the changes and all my test are successfully - looks like a fix. Many thanks.


private static void CompileRuleDefinition<T>(RuleDefinition<T> ruleDefinition)
{
    var parameter = Expression.Parameter(typeof(T));
    Expression expresion = BuildCompoundConditions(ruleDefinition, parameter);
    Expression expressionToCompile = null;
    Expression thenClause = BuildAssignExpression<T>(parameter, ruleDefinition.ThenAction);

    if (expresion != null)
    {
        if (ruleDefinition.ThenAction != null && ruleDefinition.ElseAction == null)
        {
            expressionToCompile =
                Expression.Block(
                    Expression.IfThen(
                        expresion,
                        thenClause));
        }

        if (ruleDefinition.ThenAction != null && ruleDefinition.ElseAction != null)
        {
            Expression elseClause = BuildAssignExpression<T>(parameter, ruleDefinition.ElseAction);
            expressionToCompile =
                Expression.Block(
                    Expression.IfThenElse(
                        expresion,
                        thenClause,
                        elseClause));
        }

        if (expressionToCompile != null)
        {
            ruleDefinition.CompiledExpression =
                Expression.Lambda<Action<T>>(expressionToCompile, parameter).Compile();
        }
    }
}


我通过删除外部异常块进一步完善了解决方案:

I have further refined the solution by removing the outer Exception block:
private static void CompileRuleDefinition<T>(RuleDefinition<T> ruleDefinition)
{
    var parameter = Expression.Parameter(typeof(T));
    Expression expresion = BuildCompoundConditions(ruleDefinition, parameter);
    Expression expressionToCompile = null;
    Expression thenClause = BuildAssignExpression<T>(parameter, ruleDefinition.ThenAction);

    if (expresion != null)
    {
        if (ruleDefinition.ThenAction != null && ruleDefinition.ElseAction == null)
        {
            expressionToCompile = Expression.IfThen(expresion, thenClause);
        }

        if (ruleDefinition.ThenAction != null && ruleDefinition.ElseAction != null)
        {
            Expression elseClause = BuildAssignExpression<T>(parameter, ruleDefinition.ElseAction);
            expressionToCompile =
                Expression.IfThenElse(
                        expresion,
                        thenClause,
                        elseClause);
        }

        if (expressionToCompile != null)
        {
            ruleDefinition.CompiledExpression =
                Expression.Lambda<Action<T>>(expressionToCompile, parameter).Compile();
        }
    }
}


当你指定一个Func时,它有两个参数--T,和TResult:

When you specify a Func, it has two parameters - T, and TResult:
Func<T, TResult>



所以你的代码明确说:


So your code is explicitly saying:

Func<T, int>



哪个声明该函数必须返回一个整数值。

您无法摆脱返回类型: Func (T,TResult)代表(系统) [ ^ ]因为每个函数都必须有一个(即使构造函数有一个返回类型,但它在定义中是隐式的而不是显式的)尽管你可能能够替换 int 使用不同的类型,或者甚至使用 void - 但我没有尝试在这些情况下返回空洞。它取决于你编写的其余代码,我不知道它是什么样的!


Which declares that the function must return an integer value.
You can't "get rid" of the return type: Func(T, TResult) Delegate (System)[^] because every function must have one (even constructors have a return type, but it's implicit rather than explicit in the definition) though you may be able to replace int with a different type, or even with void - but I've not tried returning voids under these circumstances. It'll depend on the rest of the code you wrote and I have no idea what that looks like!


这篇关于构建表达式时,如何避免返回整数。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆