Alex Rivera | Logout

Such a thing as a calculation engine for C#?

Asked 2011-02-01T16:11:15.703
9

Is there any calculation engine for C# that can automatically recalculate dependent fields when a value changes?

Let me freestyle for a second, I'm imagining something like this..

 Field<double> quantity = Field.Create<double>("Quantity");
 Field<double> unitCost = Field.Create<double>("Unit Cost");
 Field<double> total = Field.Create<double>("Total");

 total.Calculation((q,uc) => q * uc, quantity, value);
      // would have signature something like this:
      // void Calculation<TR,T1,T1>(Func<TR,T1,T2>, Field<T1>, Field<T2>)

This would set up fields that auto-propagate dependent values.

 quantity.Value = 5.0;
 unitCost.Value = 1.5;
 Assert.That(total.Value, Is.EqualTo(7.5));

Obviously this is a simple example, the end uses would be much more akin to the calculations of a complex spreadsheet.

Thinking further it would be amazing if the field/cells would support change notification.

Edit
Report

1 Answer

5

Have you seen http://ncalc.codeplex.com ?

It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:

Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");

  e.Parameters["Pi2"] = new Expression("Pi * Pi");
  e.Parameters["X"] = 10;

  e.EvaluateParameter += delegate(string name, ParameterArgs args)
    {
      if (name == "Pi")
      args.Result = 3.14;
    };

  Debug.Assert(117.07 == e.Evaluate());

It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.

It also supports logical operators, date/time's strings and if statements.

a solution

You could possibly do automatic recalculation by implementing INotifyPropertyChanged then doing something like

  • set a field's expression this.Field.Expression = new Expression("Field1+Field2");

On notifypropertyupdated in the class

  • for each field (with reflection) that is a Function
  • if it's expression refers to the changed field then recalculate the variable.
  • on recalculation you'd need to handle the EvaluateParameter event to use reflection to find the right field and extract its value (you could cache to avoid reflection if needed)
answered 2011-02-01T16:26:52.077

Your Answer