public static void Main()
var cond = new OrCondition(
new EqCondition(new Literal("test"),
new Literal("anothertest")),
new EqCondition(new Literal("1"),
new EqCondition(new Literal("2"),
Console.WriteLine(cond.Output());
interface IExpressionBuilder
Action<IExpressionBuilder> leftBuilder,
Action<IExpressionBuilder> rightBuilder);
Action<IExpressionBuilder> leftBuilder,
Action<IExpressionBuilder> leftBuilder,
Action<IExpressionBuilder> rightBuilder);
Action<IExpressionBuilder> leftBuilder,
class ExpressionBuilder: IExpressionBuilder
private IExpression _expression;
public IExpression Build()
public IExpressionBuilder And(
Action<IExpressionBuilder> leftBuilder,
Action<IExpressionBuilder> rightBuilder)
var lBuilder = new ExpressionBuilder();
var rBuilder = new ExpressionBuilder();
leftBuilder?.Invoke(lbuilder);
rightBuilder?.Invoke(rBuilder);
_expression= new AndCondition(lBuilder.Build(),
public IExpressionBuilder And(
Action<IExpressionBuilder> leftBuilder,
Action<IExpressionBuilder> rightBuilder)
public IExpressionBuilder And(
Action<IExpressionBuilder> leftBuilder,
public IExpressionBuilder And(
Action<IExpressionBuilder> leftBuilder,
Action<IExpressionBuilder> rightBuilder);
Action<IExpressionBuilder> leftBuilder,
Action<IExpressionBuilder> leftBuilder,
Action<IExpressionBuilder> leftBuilder,
Action<IExpressionBuilder> rightBuilder);
Action<IExpressionBuilder> leftBuilder,
interface ICondition : IExpression
abstract class Condition: ICondition
public virtual string Operator =>this.GetType()
.Replace(nameof(Condition), string.Empty)
public IExpression Left{get;}
public IExpression Right{get;}
public virtual string Output()
return $"({this.Left.Output()} {this.Operator} {this.Right.Output()})";
public Condition(IExpression left,
sealed class AndCondition: Condition
sealed class OrCondition: Condition
class Literal: IExpression
private readonly object _literal;
public Literal(object literal)
new ArgumentNullException(nameof(literal));
public virtual string Output()
return _literal.ToString();
sealed class EqCondition: Condition
public override string Operator=>"=";
sealed class BetweenCondition: IExpression
private readonly IExpression _expression;
private readonly int _min;
private readonly int _max;
return $"{_expression.Output()} BETWEEN {_min} AND {_max}";