Is it possible to compile and execute new code at

2019-01-03 15:10发布

Note: Mathematical expression evaluation is not the focus of this question. I want to compile and execute new code at runtime in .NET. That being said...

I would like to allow the user to enter any equation, like the following, into a text box:

x = x / 2 * 0.07914
x = x^2 / 5

And have that equation applied to incoming data points. The incoming data points are represented by x and each data point is processed by the user-specified equation. I did this years ago, but I didn't like the solution because it required parsing the text of the equation for every calculation:

float ApplyEquation (string equation, float dataPoint)
{
    // parse the equation string and figure out how to do the math
    // lots of messy code here...
}

When you're processing boatloads of data points, this introduces quite a bit of overhead. I would like to be able to translate the equation into a function, on the fly, so that it only has to be parsed once. It would look something like this:

FunctionPointer foo = ConvertEquationToCode(equation);
....
x = foo(x);  // I could then apply the equation to my incoming data like this

Function ConvertEquationToCode would parse the equation and return a pointer to a function that applies the appropriate math.

The app would basically be writing new code at run time. Is this possible with .NET?

15条回答
▲ chillily
2楼-- · 2019-01-03 15:20

If all else fails, there are classes under the System.Reflection.Emit namespace which you can use to produce new assemblies, classes, and methods.

查看更多
叼着烟拽天下
3楼-- · 2019-01-03 15:21

You could start here and if you really want to get into it, Boo can be modified to meet your needs. You could also integrate LUA with .NET. Any three of these could be utilized within the body of a delegate for your ConvertEquationToCode.

查看更多
一夜七次
4楼-- · 2019-01-03 15:23

You can also create a System.Xml.XPath.XPathNavigator from an empty, "dummy" XML stream, and evaluate expressions using the XPath evaluator:

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

If you want to register variables to use within this expression, you can dynamically build XML that you can pass in the Evaluate overload that takes a XPathNodeIterator.

<context>
  <x>2.151</x>
  <y>231.2</y>
</context>

You can then write expressions like "x / 2 * 0.07914" and then x is the value of the node in your XML context. Another good thing is, you will have access to all XPath core functions, which includes mathematics and string manipulation methods, and more stuff.

If you want to take it further, you can even build your own XsltCustomContext(or ill post here on demand) where you can resolve references to extension functions and variables:

object result = Evaluate ( "my:func(234) * $myvar" );

my:func is mapped to a C#/.NET method which takes a double or int as parameter. myvar is registered as a variable within the XSLT context.

查看更多
一夜七次
5楼-- · 2019-01-03 15:23

You can try looking at either CodeDom or Lambda Expression Trees. I think either one of those should allow you to accomplish this. Expression trees are probably the better way to go but also have a higher learning curve.

查看更多
贼婆χ
6楼-- · 2019-01-03 15:25

Yes, definitely possible to have the user type C# into a text box, then compile that code and run it from within your app. We do that at my work to allow for custom business logic.

Here is an article (I haven't more than skimmed it) which should get you started:

http://www.c-sharpcorner.com/UploadFile/ChrisBlake/RunTimeCompiler12052005045037AM/RunTimeCompiler.aspx

查看更多
时光不老,我们不散
7楼-- · 2019-01-03 15:29

I don't know if it's possible to implement your ConvertEquationToCode function, however, you can generate a data structure that represents the calculation you need to perform.

For example, you could build a tree whose leaf nodes represent the input for your calculation, whose non-leaf nodes represent intermediate results, and whose root node represents the whole calculation.

It has some advantages. For example, if you're doing what-if analysis and want to change the value of one input at a time, you can recalculate the results that depend on the value that you have changed, while retaining the results that don't.

查看更多
登录 后发表回答