Use CalcEngine with List<T>

Hello

I'd like to know what is the correct implementation of CalcEngine when used with a List<T>

My need is to calculate the result of a formula with parameters stored in a T object properties for each T in a List

This is my test code, it works but i think it can be improved.


public partial class MainWindow : Window

{

    public MainWindow()

    {

        InitializeComponent();


        DataModel dataModel = new DataModel();


        foreach (var item in dataModel.Bill)

        {

            item.Total = SyncFormulaSolver.Solve(item, item.Formula);


            Debug.Print($"{item.Formula} => {item.Total}");

        }

    }

}


public class BillItem

{

    public int Id { get; set; }

    public decimal Price { get; set; }

    public decimal Quantity { get; set; }

    public string Formula { get; set; }

    public double? Total { get; set; }

}


public class DataModel

{

    public List<BillItem> Bill { get; set; }

    public DataModel()

    {

        Bill = new List<BillItem>();

        Bill.Add(new BillItem() { Id = 1, Quantity = 1, Price = 3, Formula = "= Quantity * Price + 10" });

        Bill.Add(new BillItem() { Id = 2, Quantity = 2, Price = 7, Formula = "= Quantity * Price + 10" });

        Bill.Add(new BillItem() { Id = 3, Quantity = 3, Price = 30, Formula = "= Price / Quantity + 10" });

        Bill.Add(new BillItem() { Id = 4, Quantity = 3, Price = 2, Formula = "= Price ^ 3" });

    }

}


public static class SyncFormulaSolver

{

    public static double? Solve<T>(T obj, string formulaIn)

    {

        var properties = typeof(T).GetProperties().Select(o => o.Name);


        var formula = formulaIn.Clone().ToString();


        var formulaArgs = formula.Split();


        if (formulaArgs.Length == 0) return null;


        if (formulaArgs[0] == "=")

        {

            formula = formula.Replace("=", "");


            for (int i = 1; i < formulaArgs.Length; i++)

            {

                var token = formulaArgs[i];


                if (isOperator(token)) continue;

                if (!properties.Contains(token)) continue;


                var val = obj.GetType().GetProperty(token).GetValue(obj);

                formula = formula.Replace(token, val.ToString());

            }

        }

        else

        {

            return null;

        }

        CalcData calcData = new CalcData();

        CalcEngine engine = new CalcEngine(calcData);

        string result = engine.ParseAndComputeFormula(formula);

        var e = double.TryParse(result, out var value);

        return value;

    }


    private static bool isOperator(string token)

    {

        if (token == "+") return true;

        if (token == "-") return true;

        if (token == "*") return true;

        if (token == "/") return true;

        if (token == "^") return true;

        if (token == "%") return true;

        return false;

    }

}


Thanks in advance

Michele


5 Replies 1 reply marked as answer

DM Dhanasekar Mohanraj Syncfusion Team August 12, 2022 01:59 PM UTC

Hi Michale,


We have checked the provided code snippet on our end. The code snippet related to Calculations is good enough. Could you please share what kind of difficulty you are facing with this implementation? It will be helpful for us to check on it and provide you with the solution at the earliest.


Regards,

Dhanasekar M.



MI Michele August 16, 2022 08:22 AM UTC

Hi Dhanasekar

In my snippet i use Reflection to replace Arguments with values and check for Operators.

For example, if i write formula in this way "=Price*Quantity", i can not extract the variable token and switch it with a value.

Maybe there is another way to specify values for variables whitout using reflection.


Mi





DM Dhanasekar Mohanraj Syncfusion Team August 17, 2022 02:04 PM UTC

Hi Michale,

Based on provided information we have checked the provided code snippet. There is no better way to replace the Arguments and extract the variables. As we mentioned earlier the provided code snippet for the Calculation is proper and good enough.

Please let us know if you have any other queries.

Regards,
Dhanasekar M.



MI Michele August 18, 2022 06:57 AM UTC

Hi  Dhanasekar

Thanks, i've developed by myself some code to do that.


Regards

Michele


Marked as answer

DM Dhanasekar Mohanraj Syncfusion Team August 19, 2022 01:52 PM UTC

Hi Michale,

We were happy to hear that the reported issue is resolved at your end. Also, let us know if you need any further assistance.

Regards,
Dhanasekar M.


Loader.
Up arrow icon