2 Stimmen

C# kompilieren numerischen Ausdruck

Angenommen, ich erlaube dem Benutzer die Eingabe eines beliebigen numerischen Ausdrucks, der die Verwendung des expliziten Satzes von Funktionen und vordefinierten Variablen erlaubt.

Dies zu interpretieren ist ziemlich einfach, aber was ist, wenn die Leistung ein kritischer Faktor ist?

Ich brauche einen Weg, um (in Laufzeit) eine Zeichenfolge mit einem Ausdruck in etwas zu kompilieren, die 20K mal mit verschiedenen Werten auf die Variablen ausgeführt werden kann.

2voto

Marc Gravell Punkte 970173

Sie möchten also die Zeichenfolge (eventuell) in einen typisierten Delegaten zerlegen.

Eine Möglichkeit besteht darin, die Zeichenkette in eine Expression die Sie dann zu einem Lambda kompilieren können. Dies ist ziemlich komplex, aber ich habe einige Code, der viel von diesem tun wird - aber es kann bestehende Parser, die bereits die Arbeit in vollem Umfang tun.

Als eine triviale Expression Beispiel:

    var x = Expression.Parameter(typeof(double), "x");
    var y = Expression.Parameter(typeof(double), "y");
    var body = Expression.Multiply(x, y);
    var func = Expression.Lambda<Func<double, double,double>>(body, x, y).Compile();

    double z = func(123.45, 678.90);

Das Problem ist der Rest des Parsing-Codes ;-p

Ich schrieb eine string a Expression Parser letzte Woche, aber es ist mehr Code, als ich normalerweise hier posten würde... über 300 Zeilen (ohne die Erkennung von maßgeschneiderten externen Funktionen oder benannten Argumenten (er verwendet derzeit anonyme "?"-Platzhalter)).

aber wenn (wie Sie sagen) das Interpretieren einfach ist, dann verwenden Sie vielleicht einen ähnlichen Code, um eine Expression die Sie kompilieren können?

2voto

Rinat Abdullin Punkte 22138

Linq Samples von Microsoft enthalten bereits eine Implementierung eines erweiterbaren Linq-Parsers.

sealed class Order
{
  public double SubTotal { get; set; }
  public double Shipping { get; set; }
}
static void Main()
{
  var calculateTotal = DynamicExpression
    .ParseLambda<Order, double>("SubTotal*@0+Shipping", 0.12)
    .Compile();

  var order = new Order
  {
    SubTotal = 124.99,
    Shipping = 7.99
  };
  Console.WriteLine(calculateTotal(order));
  Console.ReadLine();
}

Sie können sich die DbLinq-Projekt für Quellen oder diesen Beitrag für weitere Einzelheiten: Dynamisches Linq und Expression Parsing in .NET als Hinweis auf die Erweiterbarkeit des C#-Compilers

1voto

mmx Punkte 400975

In C# 4.0 wird es sehr einfach und unkompliziert werden. Vor C# 4.0 empfehle ich jedoch die Verwendung von Microsoft.JScript Bibliotheken, um dies zu erreichen.

Das ist alles, was Sie wollen: http://www.odetocode.com/Articles/80.aspx

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X