私は単純なルールエンジンhttp://netmatze.wordpress.com/2012/01/22/building-a-rule-engine-in-c/を見ていましたが、これと非常によく似たことをしています。次のような2つのクラスがあります。
class A
{
public List<B> ListB { get; set; }
}
Class B
{
public int ID { get; set; }
}
私のルールセットは次のようになります:
List<Rule> rules = new List<Rule>{
new Rule("listB", ExpressionType.Loop, 1, "ID")
};
クラス A のプロパティ listB を基本的に調べる式を作成しようとしています。各項目の ID プロパティをループして、少なくとも 1 つが 1 に等しいかどうかを確認します。これを行う方法に問題があります。私は現在、次のようなものを持っています(これにはハードコードされた値が設定されていますが、最終的には可能な限り一般的になるように変更されます)。この式は機能しません。コンパイル例外が発生します。
var parameterExpression = Expression.Parameter(typeof(A));
var listB = MemberExpression.Property(parameterExpression, "ListB");
var leftOperand = MemberExpression.Property(Expression.Parameter(typeof(B)), "ID");
var rightOperand = Expression.Constant(1); //1
var found = Expression.Variable(typeof(bool), "found");
return Expression.Lambda<Func<T, bool>>(
Expression.Block(
listB,
found,
Expression.Loop(
Expression.Block(
Expression.IfThen(
Expression.Equal(
leftOperand,
rightOperand
),//equal
Expression.Assign(
found,
Expression.Constant(true)
)//set to true
)
)//block
)//loop
),
A
).Compile();
次のように、オブジェクトに対してルール セットを呼び出すことになります。
Engine ruleEngine = new Engine();
var compiledRules = rules.Select(r => ruleEngine.CompileRule<A>(r)).ToList();
var result = compiledRules.All(rule => rule(objA));
私の質問は次のとおりです。
- リスト項目のいずれかが条件に一致した場合に、この関数が true/false を返すようにするにはどうすればよいですか。
- すべてのリスト項目が比較された後 (そしてどれも一致しなかった場合)、Expression.Loop がループを停止するのを防ぐにはどうすればよいですか?
助けてくれてありがとう。