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));
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)