Table of Contents

Parameters

Static Parameters

Static parameters are values which can be defined before the evaluation of an expression. These parameters can be accessed using the Parameters property of the Expression instance.

var expression = new Expression("2 * [x] ** 2 + 5 * [y]");
expression.Parameters["x"] = 5;
expression.Parameters["y"] = 1;

Console.WriteLine(expression.Evaluate());

Parameters can be useful when a value is unknown at compile time, or when performance is important and the parsing can be saved for further calculations.

Expression Parameters

Expressions can be split into several ones by defining expression parameters. Those parameters are not simple values but Expression instances themselves.

Expression volume = new Expression("[surface] * h");
Expression surface = new Expression("[l] * [L]");
volume.Parameters["surface"] = surface;
surface.Parameters["l"] = 1;
surface.Parameters["L"] = 2;

Dynamic Parameters

Sometimes parameters can be even more complex to evaluate and need a dedicated method to be evaluated. This can be done using the ExpressionParameter delegate.

var expression = new Expression("Round(Pow([Pi], 2) + Pow([Pi], 2) + [X], 2)");

expression.Parameters["Pi2"] = new Expression("Pi * [Pi]");
expression.Parameters["X"] = 10;

expression.DynamicParameters["Pi"] = _ => 
{
    Console.WriteLine("I'm evaluating π!");
    return 3.14;
};

Square Brackets Parameters

Parameters in between square brackets can contain special characters like spaces, dots, and also start with digits.

var expression = new Expression("[My First Parameter] + [My Second Parameter]");

Curly Braces Parameters

In Allied Bits NCalc, curly braces are used to group expressions. So while the '{PageState}' will work when referencing the value of the parameter, assigning to '{PageState}' will not work (use square brackets instead).

Multi-Valued Parameters

When parameters are IEnumerable and the IterateParameters is used, the result is a List<object?> made of the evaluation of each value in the parameter.

var expression = new Expression("(a * b) ** c", ExpressionOptions.IterateParameters);
expression.Parameters["a"] = new int[] { 1, 2, 3, 4, 5 };
expression.Parameters["b"] = new int[] { 6, 7, 8, 9, 0 };
expression.Parameters["c"] = 3;

foreach (var result in (IList)expression.Evaluate())
{
    Console.WriteLine(result);
}

//  216
//  2744
//  13824
//  46656
//  0

Indexed parameters

If a parameter contains a list of values (IList), it is possible to access an element by accessing the variable and specifying a zero-based index (which may be an expression):

var expression = new Expression("a := (1,2,3); a[ 2 / 2 ]", ExpressionOptions.UseAssignments);

Using Event Handlers

You can also use event handlers to handle parameters.

expression.EvaluateParameter += delegate(string name, ParameterArgs args)
{
    if (name == "Pi")
        args.Result = 3.14;
};

Compare with Null Parameters

When parameter is null and the AllowNullParameter flag is used, comparison of values to null is allowed.

var expression = new Expression("'a string' == null", ExpressionOptions.AllowNullParameter);
(bool)expression.Evaluate();

//  False

Getting all Parameters from an Expression

var expression = new Expression ("if(x=0,x,y)"); 
expression.Parameters["x"] = 1;
expression.Parameters["y"] = "pan";
var parameters = expression.GetParametersNames(); 
//  x
//  y

Case Sensitivity

See case_sensitivity for more info.

Assigning and Updating Parameters

Parameters can be assigned in expressions. Support for assignments must be enabled by including the UseAssignments flag into ExpressionOptions of an Expression or AsyncExpression.

When a parameter is assigned, first the UpdateParameter event is fired. An event handler may tell the evaluation engine to update the static parameter table or bypass this step by setting the UpdateParameterArgs.UpdateParameterLists or AsyncUpdateParameterArgs.UpdateParameterLists property to true or false respectively.

An assignment is an expression, so it can be used wherever a value is accepted. E.g., the following operations are equivalent:

if (true, a := 2, a := 4); a + Max(2; 4)
a := if (true; 2; 4); a + Max(2; 4)

Assignment can be combined with an operator (such as "+=" for addition with assignment); please, see the Operators topic for the list of supported operators with assignment.

Assignment may be combined with indexed access:

a := (1; 2; 3); a[1] := -2;