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;
};
Async dynamic parameters
When parameter resolution needs asynchronous I/O, use AsyncParameters together with EvaluateAsync(CancellationToken).
var expression = new Expression("userName == 'alice'");
expression.AsyncParameters["userName"] = async args =>
{
await Task.Delay(100, args.CancellationToken);
return "alice";
};
Serializing expressions with parameter values
To inspect the expression text with known parameters replaced by their current values, use the
ToExpressionString(bool, CancellationToken)
method with evaluateParameters set to true.
var expression = new Expression("[ValueA] + [ValueB]");
expression.Parameters["ValueA"] = 10;
expression.Parameters["ValueB"] = 15;
var expressionText = expression.ToExpressionString(evaluateParameters: true);
// 10 + 15
Parameters that cannot be resolved are left in the output, for example 10 + [ValueB].
Function calls are preserved as function calls, with any known parameter arguments substituted.
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
You can also use a curly braces as alternative to square brackets.
var expression = new Expression("{PageState} == 'List'");
Multi-valued parameters
When parameters are IEnumerable and IterateParameters is enabled, the result
is a List<object?> made of the evaluation of each value in the parameter.
var configuration = new ExpressionConfiguration
{
Evaluation = new ExpressionEvaluationOptions
{
IterateParameters = true
}
};
var expression = new Expression("(a * b) ** c", configuration);
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
Using Event Handlers
You can also use event handlers to handle parameters.
expression.EvaluateParameter += delegate(string name, ParameterEventArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
For asynchronous parameter resolution, use EvaluateAsyncParameter. During EvaluateAsync(), NCalc checks
EvaluateParameter first and only calls EvaluateAsyncParameter if the synchronous handler did not set Result.
expression.EvaluateAsyncParameter += async (name, args) =>
{
if (name != "tenantId")
return;
await Task.Delay(100, args.CancellationToken);
args.Result = 42;
};
Compare with null parameters
When AllowNullParameter is enabled, comparison of values to null is allowed.
var configuration = new ExpressionConfiguration
{
Evaluation = new ExpressionEvaluationOptions
{
AllowNullParameter = true
}
};
var expression = new Expression("'a string' == null", configuration);
(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.GetParameterNames();
// x
// y
Case Sensitivity
See case_sensitivity for more info.