rav*_*ven 33 .net c# runtime compilation
注意:数学表达式评估不是这个问题的焦点.我想在.NET中运行时编译和执行新代码. 话虽如此...
我想允许用户在文本框中输入任何等式,如下所示:
x = x / 2 * 0.07914
x = x^2 / 5
Run Code Online (Sandbox Code Playgroud)
并将该等式应用于传入的数据点.输入数据点由x表示,每个数据点由用户指定的等式处理.我多年前做过,但我不喜欢这个解决方案,因为它需要为每次计算解析等式的文本:
float ApplyEquation (string equation, float dataPoint)
{
// parse the equation string and figure out how to do the math
// lots of messy code here...
}
Run Code Online (Sandbox Code Playgroud)
当您处理大量数据点时,这会引入相当多的开销.我希望能够在飞行中将方程转换为函数,这样它只需要解析一次.它看起来像这样:
FunctionPointer foo = ConvertEquationToCode(equation);
....
x = foo(x); // I could then apply the equation to my incoming data like this
Run Code Online (Sandbox Code Playgroud)
函数ConvertEquationToCode将解析方程并返回指向应用适当数学的函数的指针.
该应用程序基本上是在运行时编写新代码.这可能与.NET有关吗?
rav*_*ven 18
是! 使用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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Bri*_*itt 13
你可以试试这个: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");
Run Code Online (Sandbox Code Playgroud)
下载页面 并根据BSD许可证分发.
是的,绝对可以让用户在文本框中键入C#,然后编译该代码并在您的应用程序中运行它.我们在工作中这样做是为了允许自定义业务逻辑.
这是一篇文章(我只是撇去它),它应该让你开始:
您还可以从空的"虚拟"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 ( "<r/>" ) ).CreateNavigator ( );
Run Code Online (Sandbox Code Playgroud)
如果要注册要在此表达式中使用的变量,可以动态构建可以在带有XPathNodeIterator的Evaluate重载中传递的XML.
<context>
<x>2.151</x>
<y>231.2</y>
</context>
Run Code Online (Sandbox Code Playgroud)
然后,您可以编写类似"x/2*0.07914"的表达式,然后x是XML上下文中节点的值.另一个好处是,您可以访问所有XPath核心功能,包括数学和字符串操作方法,以及更多内容.
如果你想进一步,你甚至可以构建自己的XsltCustomContext(或在这里按需发布帖子),你可以在其中解析对扩展函数和变量的引用:
object result = Evaluate ( "my:func(234) * $myvar" );
Run Code Online (Sandbox Code Playgroud)
my:func映射到C#/ .NET方法,该方法采用double或int作为参数.myvar在XSLT上下文中注册为变量.