基于AST使用And Or和Not表达的C#表达式

时间:2009-08-14 07:23:40

标签: c# .net linq lambda

我想将Linq表达式用于某些动态功能。我需要And,Or和Not表达式..我不能得到太多......

我们要检查系统中是否启用了某些功能,并根据该功能决定是否显示菜单项。我们已经形成了XML格式的规则,我知道将规则转换为AST,但我不知道要映射到Linq表达式。

规则如下:Feature1Enabled和Feature2Eenabled或(Feature3Disabled而非Feature5Enabled)

此处“Feature1Enabled”,“Feature2Eenabled”等是该功能的名称。我们将此字符串传递给IsFeatureEnabled函数以检查是否已启用某个功能。

  public delegate bool IsEnabledDelegate(string name, string value);

    public static bool IsFeatureEnabled(string name, string value)
    {
        if (name == "MV")
            return true;

        if (name == "GAS" && value == "G")
            return true;
        //More conditions goes here
        return false;
    }

    static void Main(string[] args)
    {
        Expression<Func<string, string, bool>> featureEnabledExpTree = 
                      (name, value) => IsFeatureEnabled(name, value);

        //I want the equal of the following statement in C# Linq Expression

       bool result = IsFeatureEnabled("MV", "") && IsFeatureEnabled("GAS", "G") || !IsFEatureEnabled("GAS", "F")

    }

我想要相当于      bool result = IsFeatureEnabled(“MV”,“”)&amp;&amp; IsFeatureEnabled(“GAS”,“G”)|| !IsFEatureEnabled(“GAS”,“F”)

in Linq expression Format ..但是我可以根据我的AST符号动态转换它们。

非常感谢..如果您需要更多信息,请在评论中告诉我..

2 个答案:

答案 0 :(得分:5)

    ParameterExpression name = Expression.Parameter(typeof(string), "name"),
        value = Expression.Parameter(typeof(string), "value");

    // build in reverse
    Expression body = Expression.Constant(false);
    body = Expression.Condition(
        Expression.AndAlso(
            Expression.Equal(name, Expression.Constant("GAS")),
            Expression.Equal(value, Expression.Constant("G"))
        ), Expression.Constant(true), body);
    body = Expression.Condition(
        Expression.Equal(name, Expression.Constant("MV")),
        Expression.Constant(true), body);

    Expression<Func<string, string, bool>> featureEnabledExpTree =
        Expression.Lambda<Func<string, string, bool>>(body, name, value);


    // test in isolation
    var featureEnabledFunc = featureEnabledExpTree.Compile();
    bool isMatch1 = featureEnabledFunc("MV", "")
        && featureEnabledFunc("GAS", "G") || !featureEnabledFunc("GAS", "F");

然后,如果您还需要 second 部分作为表达式树:

    //I want the equal of the following statement in C# Linq Expression
    Expression<Func<bool>> test =
        Expression.Lambda<Func<bool>>(
            Expression.OrElse(
                Expression.AndAlso(
                    Expression.Invoke(featureEnabledExpTree,
                        Expression.Constant("MV"),
                        Expression.Constant("")
                    ),
                    Expression.Invoke(featureEnabledExpTree,
                        Expression.Constant("GAS"),
                        Expression.Constant("G")
                    )
                ),
                Expression.Not(
                    Expression.Invoke(featureEnabledExpTree,
                        Expression.Constant("GAS"),
                        Expression.Constant("F")
                    )
                )
            )
        );

    bool isMatch = test.Compile()();

答案 1 :(得分:1)

是那样的?

Expression<Func<bool>> featureEnabledExpTree = () =>
    IsFeatureEnabled("MV", "") &&
    IsFeatureEnabled("GAS", "G") ||
    !IsFEatureEnabled("GAS", "F");