I am trying to refactor this code into a more elegant version. Can anyone please help.
- The issue is where to as sign the first evaluation result for comparision later on?
- And I want to eliminate the use of if/switch if possible
- Should I remove Operator class and split Eval into And and Or class, but wouldn't be too much differnt I think
public interface IEval<T>
{
Func<T, bool> Expression { get; }
Operator Operator { get; }
string Key { get; }
}
public static bool Validate<T>(this T o, IList<IEval<T>> conditions)
{
var returnResult = true;
var counter = 0;
foreach (var condition in conditions)
{
var tempResult = condition.Expression(o);
if (counter == 0) //don't like this
{
returnResult = tempResult;
counter++;
}
else
{
switch (condition.Operator) //don't like this
{
case Operator.And:
returnResult &= tempResult;
break;
case Operator.Or:
returnResult |= tempResult;
break;
default:
throw new NotImplementedException();
}
}
}
return returnResult;
}
Thanks!
Code Updated:
public interface IEval<T>
{
Func<T, bool> Expression { get; }
bool Eval(bool against, T t);
}
public class AndEval<T> : IEval<T>
{
public Func<T, bool> Expression { get; private set; }
public AndEval(Func<T, bool> expression)
{
Expression = expression;
}
public bool Eval(bool against, T t)
{
return Expression.Invoke(t) & against;
}
}
public class OrEval<T> : IEval<T>
{
public Func<T, bool> Expression { get; private set; }
public OrEval(Func<T, bool> expression)
{
Expression = expression;
}
public bool Eval(bool against, T t)
{
return Expression.Invoke(t) | against;
}
}
public static class EvalExtensions
{
public static bool Validate<T>(this T t, IList<IEval<T>> conditions)
{
var accumulator = conditions.First().Expression(t);
foreach (var condition in conditions.Skip(1))
{
accumulator = condition.Eval(accumulator, t);
}
return accumulator;
}
}