2

The code of NRules SimpleRule define the following rule:

public class PreferredCustomerDiscountRule : Rule
{
    public override void Define()
    {
        Customer customer = null;
        IEnumerable<Order> orders = null;

        When()
            .Match<Customer>(() => customer, c => c.IsPreferred)
            .Collect<Order>(() => orders,
                o => o.Customer == customer,
                o => o.IsOpen,
                o => !o.IsDiscounted);

        Then()
            .Do(ctx => ApplyDiscount(orders, 10.0))
            .Do(ctx => LogOrders(orders))
            .Do(ctx => orders.ToList().ForEach(ctx.Update));
    }
        ...
}

I am wondering why the conditions are seperate pareameters in stead of just using && operator i.e. will the following have the same effect?

public class PreferredCustomerDiscountRule : Rule
{
    public override void Define()
    {
        Customer customer = null;
        IEnumerable<Order> orders = null;

        When()
            .Match<Customer>(() => customer, c => c.IsPreferred)
            .Collect<Order>(() => orders,
                o => o.Customer == customer && o.IsOpen && !o.IsDiscounted);

        Then()
            .Do(ctx => ApplyDiscount(orders, 10.0))
            .Do(ctx => LogOrders(orders))
            .Do(ctx => orders.ToList().ForEach(ctx.Update));
    }
        ...
}
4

2 回答 2

12

提供单个条件表达式和提供多个条件表达式之间存在差异。

在幕后,规则被编译成一个网络(rete network),每个条件都由网络中的一个节点表示。当多个规则共享相同的条件子集时,这些节点会在网络中共享,从而提高效率(因为要评估的条件更少)。由于节点共享,提供多个条件表达式为引擎提供了更多优化机会。

另一个区别是条件短路。使用“&&”运算符提供单个条件表达式时,将应用标准 C# 条件短路。如果第一个条件为假,则不评估第二个条件。当提供多个条件时,这不一定是正确的(因为优化是由引擎在不同级别完成的)。

最佳实践是使用多个条件表达式,而不是使用带有 '&&' 的单个条件表达式。

于 2015-07-24T02:07:28.870 回答
1

这两个定义应该做同样的事情。CollectExpression<Func<T, bool>>方法需要一个. 第一个将其拆分为 3 个单独的条件,而第二个仅使用一个条件(与组合)。

我认为这是一个品味问题,你喜欢哪一个。但是对于第一个,它很清楚哪些条件是相关的,您可以轻松删除或添加条件(通过评论 //)。

于 2015-06-01T11:33:35.187 回答