Если все таки компиляцию, то можно так:
| Код | public static class Evaluator { private const string codePart1 = "using System; public static class "; private const string codePart2 = "_Calc_"; private const string codePart3 = " { public static double "; private const string codePart4 = "Eval"; private const string codePart5 = "() { return "; private const string codePart6 = "; } }";
public static double Evaluate(string expression) { CSharpCodeProvider codeProvider = new CSharpCodeProvider(); CompilerParameters param = new CompilerParameters { GenerateInMemory = true }; CompilerResults result = codeProvider.CompileAssemblyFromSource(param, string.Concat(codePart1, codePart2, codePart3, codePart4, codePart5, expression, codePart6));
if (result.Errors.HasErrors) throw new InvalidOperationException(string.Format("Произошла ошибка во время компиляции выражения:\r\n{0}", string.Join("\r\n", result.Errors.OfType<CompilerError>())));
Type type = result.CompiledAssembly.GetType(codePart2); if (type == null) throw new InvalidOperationException("Непредвиденная ошибка (тип не найден).");
return (double)type.InvokeMember(codePart4, BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, null); } }
|
используешь так:
| Код | MessageBox.Show(Evaluator.Evaluate("(23+2)*2").ToString()); MessageBox.Show(Evaluator.Evaluate("Math.Sin(Math.PI) * Math.Cos(Math.PI)").ToString());
|
Но имей ввиду, что компиляция процесс не быстрый, так что пользуйся, только если производительность тебя устраивает. Но я бы на твоем месте сделал нотацию, тем более ,что делов там не много. Можно еще построить дерево выражений (Expression), но тоже вариант не производительный. |