注意:数学表达式评估不是这个问题的焦点.我想在.NET中运行时编译和执行新代码. 话虽如此...
我想允许用户在文本框中输入任何等式,如下所示:
x = x / 2 * 0.07914 x = x^2 / 5
并将该等式应用于传入的数据点.输入数据点由x表示,每个数据点由用户指定的等式处理.我多年前做过,但我不喜欢这个解决方案,因为它需要为每次计算解析等式的文本:
float ApplyEquation (string equation, float dataPoint) { // parse the equation string and figure out how to do the math // lots of messy code here... }
当您处理大量数据点时,这会引入相当多的开销.我希望能够在飞行中将方程转换为函数,这样它只需要解析一次.它看起来像这样:
FunctionPointer foo = ConvertEquationToCode(equation); .... x = foo(x); // I could then apply the equation to my incoming data like this
函数ConvertEquationToCode将解析方程并返回指向应用适当数学的函数的指针.
该应用程序基本上是在运行时编写新代码.这可能与.NET有关吗?
是! 使用Microsoft.CSharp,System.CodeDom.Compiler和System.Reflection名称空间中的方法.这是一个简单的控制台应用程序,它使用一种方法("Add42")编译一个类("SomeClass"),然后允许您调用该方法.这是一个简单的例子,我格式化以防止滚动条出现在代码显示中.它只是演示在运行时编译和使用新代码.
using Microsoft.CSharp; using System; using System.CodeDom.Compiler; using System.Reflection; namespace RuntimeCompilationTest { class Program { static void Main(string[] args) { string sourceCode = @" public class SomeClass { public int Add42 (int parameter) { return parameter += 42; } }"; var compParms = new CompilerParameters{ GenerateExecutable = false, GenerateInMemory = true }; var csProvider = new CSharpCodeProvider(); CompilerResults compilerResults = csProvider.CompileAssemblyFromSource(compParms, sourceCode); object typeInstance = compilerResults.CompiledAssembly.CreateInstance("SomeClass"); MethodInfo mi = typeInstance.GetType().GetMethod("Add42"); int methodOutput = (int)mi.Invoke(typeInstance, new object[] { 1 }); Console.WriteLine(methodOutput); Console.ReadLine(); } } }
你可以试试这个:Calculator.Net
它将评估数学表达式.
从发布它将支持以下内容:
MathEvaluator eval = new MathEvaluator(); //basic math double result = eval.Evaluate("(2 + 1) * (1 + 2)"); //calling a function result = eval.Evaluate("sqrt(4)"); //evaluate trigonometric result = eval.Evaluate("cos(pi * 45 / 180.0)"); //convert inches to feet result = eval.Evaluate("12 [in->ft]"); //use variable result = eval.Evaluate("answer * 10"); //add variable eval.Variables.Add("x", 10); result = eval.Evaluate("x * 10");
下载页面 并根据BSD许可证分发.
是的,绝对可以让用户在文本框中键入C#,然后编译该代码并在您的应用程序中运行它.我们在工作中这样做是为了允许自定义业务逻辑.
这是一篇文章(我只是撇去它),它应该让你开始:
http://www.c-sharpcorner.com/UploadFile/ChrisBlake/RunTimeCompiler12052005045037AM/RunTimeCompiler.aspx
您还可以从空的"虚拟"XML流创建System.Xml.XPath.XPathNavigator,并使用XPath评估程序计算表达式:
static object Evaluate ( string xp ) { return _nav.Evaluate ( xp ); } static readonly System.Xml.XPath.XPathNavigator _nav = new System.Xml.XPath.XPathDocument ( new StringReader ( "" ) ).CreateNavigator ( );
如果要注册要在此表达式中使用的变量,可以动态构建可以在带有XPathNodeIterator的Evaluate重载中传递的XML.
2.151 231.2
然后,您可以编写类似"x/2*0.07914"的表达式,然后x是XML上下文中节点的值.另一个好处是,您可以访问所有XPath核心功能,包括数学和字符串操作方法,以及更多内容.
如果你想进一步,你甚至可以构建自己的XsltCustomContext(或在这里按需发布帖子),你可以在其中解析对扩展函数和变量的引用:
object result = Evaluate ( "my:func(234) * $myvar" );
my:func映射到C#/ .NET方法,该方法采用double或int作为参数.myvar在XSLT上下文中注册为变量.