Functions/FunctionBase.cs
using System;
using Expressive.Exceptions;
using Expressive.Expressions;
using System.Collections.Generic;
using System.Linq;
namespace Expressive.Functions
{
/// <summary>
/// Base class implementation for providing a function that can be registered and evaluated.
/// </summary>
public abstract class FunctionBase : IFunction
{
#region IFunction Members
/// <inheritdoc />
#pragma warning disable CA2227 // Collection properties should be read only - it is likely this can be passed in to Evaluate but it will need to be done carefully (e.g. mark this setter as obsolete first).
public IDictionary<string, object> Variables { get; set; }
#pragma warning restore CA2227 // Collection properties should be read only
/// <inheritdoc />
public abstract string Name { get; }
/// <inheritdoc />
public abstract object Evaluate(IExpression[] parameters, Context context);
#endregion
/// <summary>
/// Validates whether the expected number of parameters are present.
/// </summary>
/// <param name="parameters">The parameters.</param>
/// <param name="expectedCount">The expected number of parameters, use -1 for an unknown number.</param>
/// <param name="minimumCount">The minimum number of parameters.</param>
protected void ValidateParameterCount(IExpression[] parameters, int expectedCount, int minimumCount)
{
if (parameters is null)
{
throw new ArgumentNullException(nameof(parameters));
}
if (expectedCount == 0 && (parameters.Any() || parameters.Length != expectedCount))
{
throw new ParameterCountMismatchException($"{this.Name}() does not take any arguments");
}
if (expectedCount > 0 && (!parameters.Any() || parameters.Length != expectedCount))
{
throw new ParameterCountMismatchException($"{this.Name}() takes only {expectedCount} argument(s)");
}
if (minimumCount > 0 && (!parameters.Any() || parameters.Length < minimumCount))
{
throw new ParameterCountMismatchException($"{this.Name}() expects at least {minimumCount} argument(s)");
}
}
}
}