Programmatically build an expression

Build an expression with C# code

On top of the existing Expressif language, you can also build expressions directly from C# code. To achieve this, you should use the class ExpressionBuilder. This class has a method Chain to let you define the functions composing your expression. Each call to the method Chain lets you add a function to the expression. Once all the functions have been added, you must call the method build to retrieve your expression. This expression can be used as any other expression by calling the Evaluate method.

var builder = new ExpressionBuilder()
    .Chain<Lower>()
    .Chain<Length>();
var expression = builder.Build();
Assert.That(expression.Evaluate("Nikola Tesla"), Is.EqualTo(12));

For the functions requiring one or more parameters, you can specify them as arguments of the function Chain.

var builder = new ExpressionBuilder().Chain<PadRight>(15, '*');
var expression = builder.Build();
Assert.That(expression.Evaluate("Nikola Tesla"), Is.EqualTo("Nikola Tesla***"));

You can use the context values as parameters of the function.

var context = new Context();
var builder = new ExpressionBuilder(context)
    .Chain<Lower>()
    .Chain<PadRight>(ctx => ctx.Variables["myVar"], ctx => ctx.CurrentObject[1]);
var expression = builder.Build();

context.Variables.Add<int>("myVar", 15);
context.CurrentObject.Set(new List<char>() { '-', '*', ' ' });
Assert.That(expression.Evaluate("Nikola Tesla"), Is.EqualTo("nikola tesla***"));

context.Variables.Set("myVar", 16);
context.CurrentObject.Set(new List<char>() { '*', '+' });
Assert.That(expression.Evaluate("Nikola Tesla"), Is.EqualTo("nikola tesla++++"));

You can build your final expression by combining other expressions. Use also the function Chain with an expression as parameter. Using subexpression to define a parameter of a function is currently not supported.

var subExpressionBuilder = new ExpressionBuilder()
    .Chain<FirstChars>(5)
    .Chain<PadRight>(7, '*');

var builder = new ExpressionBuilder()
    .Chain<Lower>()
    .Chain(subExpressionBuilder)
    .Chain<Upper>();

var expression = builder.Build();
Assert.That(expression.Evaluate("Nikola Tesla"), Is.EqualTo("NIKOL**"));

If you don’t like generics (or if you cannot use them), you can also use the override of the method Chain accepting types.

var builder = new ExpressionBuilder()
    .Chain(typeof(Lower))
    .Chain(typeof(FirstChars), 5)
    .Chain(typeof(PadRight), 7, '*');
var expression = builder.Build();
Assert.That(expression.Evaluate("Nikola Tesla"), Is.EqualTo("nikol**"));

Temporal predicates
Programmatically build a predication