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(); } } }