1

Trying to figure out which approach to use in .net/C# to evaluate a simple expression in runtime. Code must be .net standard compliant, and I dont want weird dependecies.

I have looked into using using Microsoft.CodeAnalysis.CSharp.Scripting: How can I evaluate C# code dynamically? but it seems overkill for my use case.

public class Evaluate
    {
        private Dictionary<string, object> _exampleVariables = new Dictionary<string, object>
        {
            {"x", 45},
            {"y", 0},
            {"z", true}
        };
        private string _exampleExpression = "x>y || z";
        private string _exampleExpression2 = @"if(x>y || z) return 10;else return 20;
";
        public object Calculate(Dictionary<string, object> variables, string expression)
        {
            var result = //Magical code
            return result;
        }
    }
jsandv
  • 276
  • 4
  • 20
  • Is this what you are looking? [Evaluating string “3*(4+2)” yield int 18](https://stackoverflow.com/questions/333737/evaluating-string-342-yield-int-18) – SᴇM Jun 13 '19 at 12:36
  • Yes, it looks promising and accepted answer seems similar to Microsoft.CodeAnalysis.CSharp.Scripting. Im worried about the power though. User can get access to more resources then the result of the expression. – jsandv Jun 13 '19 at 12:46
  • Without knowing what you mean by "simple" it is hard to say. I would not call Example 2 simple - what other statements are allowed? Also, why does Example 2 need `return`? – NetMage Jun 13 '19 at 22:39
  • Here is my [infix expression evalutor](https://stackoverflow.com/a/44268877/2557128). Expansion to handle variables and multi-digit values and expression statements are left to the reader. – NetMage Jun 13 '19 at 22:42
  • @NetMage example 2 only shows the possibility to write expression as an if else statement. – jsandv Jun 26 '19 at 03:27
  • @Snovva1 Are other statements allowed? Again, no longer simple expression evaluation. OTOH, you could add support for the ternary operator if it is just if/else. – NetMage Jun 26 '19 at 17:07

2 Answers2

3

You can try my Matheval library. It can evaluate string expression in pure C# and support IFELSE, SWITCH statement. I don't use any dependencies.

using System;
using org.matheval;
                    
public class Program
{
    public static void Main()
    {
        Expression expression = new Expression("IF(time>8, (HOUR_SALARY*8) + (HOUR_SALARY*1.25*(time-8)), HOUR_SALARY*time)");
        //bind variable
        expression.Bind("HOUR_SALARY", 10);
        expression.Bind("time", 9);
        //eval
        Decimal salary = expression.Eval<Decimal>();    
        Console.WriteLine(salary);
    }
}

View my repo at: https://github.com/matheval/expression-evaluator-c-sharp/

Binh
  • 261
  • 2
  • 4
0

In C# you can do this:

class Program
{
    private static Func<Dictionary<string, object>, object> function1 = x =>
    {
        return ((int)x["x"] > (int)x["y"]) || (bool)x["z"];
    };

    private static Func<Dictionary<string, object>, object> function2 = x =>
    {
        if (((int)x["x"] > (int)x["y"]) || (bool)x["z"])
        {
            return 10;
        }
        else
        {
            return 20;
        }
    };

    static void Main(string[] args)
    {
        Dictionary<string, object> exampleVariables = new Dictionary<string, object>
        {
            {"x", 45},
            {"y", 0},
            {"z", true}
        };

        Console.WriteLine(Calculate(exampleVariables, function2));
    }

    public static object Calculate(Dictionary<string, object> variables, Func<Dictionary<string, object>, object> function)
    {
        return function(variables);
    }
}
Marco Salerno
  • 5,131
  • 2
  • 12
  • 32
  • Thanks for trying, but unless im reading this wrong, then you create a concrete solution to example fields. Their intent was only to give and idea of what the Calculate method had to deal with. Expression can be anything: "true && true && false", user enters it in runtime. – jsandv Jun 13 '19 at 12:51
  • I made it to show you that you can make a method which can evaluate in different ways, anyway it doesn't work in real time – Marco Salerno Jun 13 '19 at 12:52