using System;
using System.Reflection;
using LoreSoft.MathExpressions.Properties;
using System.Globalization;
namespace LoreSoft.MathExpressions
{
///
/// A class representing the System.Math function expressions
///
public class FunctionExpression : ExpressionBase
{
// must be sorted
/// The supported math functions by this class.
private static readonly string[] mathFunctions = new string[]
{
"abs", "acos", "asin", "atan", "ceiling", "cos", "cosh", "exp",
"floor", "log", "log10", "sin", "sinh", "sqrt", "tan", "tanh"
};
/// Initializes a new instance of the class.
/// The function name for this instance.
public FunctionExpression(string function) : this(function, true)
{
}
/// Initializes a new instance of the class.
/// The function.
/// if set to true to validate the function name.
internal FunctionExpression(string function, bool validate)
{
function = function.ToLowerInvariant();
if (validate && !IsFunction(function))
throw new ArgumentException(
string.Format(CultureInfo.CurrentCulture, Resources.InvalidFunctionName, _function),
"function");
_function = function;
base.Evaluate = new MathEvaluate(Execute);
}
private string _function;
/// Gets the name function for this instance.
/// The function name.
public string Function
{
get { return _function; }
}
/// Executes the function on specified numbers.
/// The numbers used in the function.
/// The result of the function execution.
/// When numbers is null.
/// When the length of numbers do not equal .
public double Execute(double[] numbers)
{
base.Validate(numbers);
string function = char.ToUpperInvariant(_function[0]) + _function.Substring(1);
MethodInfo method = typeof (Math).GetMethod(
function,
BindingFlags.Static | BindingFlags.Public,
null,
new Type[] { typeof(double) },
null);
if (method == null)
throw new InvalidOperationException(
string.Format(CultureInfo.CurrentCulture,
Resources.InvalidFunctionName, _function));
object[] parameters = new object[numbers.Length];
Array.Copy(numbers, parameters, numbers.Length);
return (double) method.Invoke(null, parameters);
}
/// Gets the number of arguments this expression uses.
/// The argument count.
public override int ArgumentCount
{
get { return 1; }
}
/// Determines whether the specified function name is a function.
/// The function name.
/// true if the specified name is a function; otherwise, false.
public static bool IsFunction(string function)
{
return (Array.BinarySearch(
mathFunctions, function,
StringComparer.OrdinalIgnoreCase) >= 0);
}
/// Returns a that represents the current .
/// A that represents the current .
/// 2
public override string ToString()
{
return _function;
}
///
/// Gets the function names.
///
/// An array of function names.
public static string[] GetFunctionNames()
{
return (string[])mathFunctions.Clone();
}
}
}