Is there an eval function In C#?
Asked Answered
P

8

18

I'm typing an equation into a TextBox that will generate the graph of the given parabola. Is it possible to use an eval function? I'm using C# 2010 and it doesn't have Microsoft.JScript

Putup answered 19/5, 2011 at 0:50 Comment(0)
B
40

C# doesn't have a comparable Eval function but creating one is really easy:

public static double Evaluate(string expression)  
       {  
           System.Data.DataTable table = new System.Data.DataTable();  
           table.Columns.Add("expression", string.Empty.GetType(), expression);  
           System.Data.DataRow row = table.NewRow();  
           table.Rows.Add(row);  
           return double.Parse((string)row["expression"]);  
       }

Now simply call it like this:

Console.WriteLine(Evaluate("9 + 5"));
Beaufort answered 19/5, 2011 at 0:58 Comment(7)
Wow. That's really sneaky =)Antimere
If you're using this to plot graph, a variation on this can be used to generate the function values. Have one column in the DataTable called "x", and put your expression for f(x) in the other column?Antimere
Note that this only evaluates very simple math expressions. And for better performance you could keep the datatable outside of the function.Pillar
since this only evaluates very simple, im looking for something to evaluate ax^2 + bx + c is there a way?Putup
If you're allowed to use a 3rd parth library, use NCalcBeaufort
Just to update @TeomanSoygul's comment, with CodePlex closing shortly, NCalc will be found here.Read
wow, you can even eval test stored in string.. var toto = 0; Console.WriteLine(Eval(toto + "= 0"));Jabin
S
19

You can easily do this with the "Compute" method of the DataTable class.

static Double Eval(String expression)
{
    System.Data.DataTable table = new System.Data.DataTable();
    return Convert.ToDouble(table.Compute(expression, String.Empty));
}

Pass a term in form of a string to the function in order to get the result.

Double result = Eval("7 * 6");
result = Eval("17 + 4");
...
Stroh answered 14/8, 2014 at 17:24 Comment(2)
+1. Also, using System.Data must be included and an assembly reference must be added for System.Data.Gordan
this will not support any tertiary operator like 13.67113 < 8 ? 28.336489999999998 : 13.67113Juli
M
8

You can create one yourself by using CodeDom. It will be slow because it creates a new assembly every time you call Eval.

public class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(ExpressionEvaluator.Eval("(2 + 2) * 2"));
    }
}

public class ExpressionEvaluator
{
    public static double Eval(string expression)
    {
        CSharpCodeProvider codeProvider = new CSharpCodeProvider();
        CompilerResults results =
            codeProvider
            .CompileAssemblyFromSource(new CompilerParameters(), new string[]
            {
                string.Format(@"
                    namespace MyAssembly
                    {{
                        public class Evaluator
                        {{
                            public double Eval()
                            {{
                                return {0};
                            }}
                        }}
                    }}

                ",expression)
            });

        Assembly assembly = results.CompiledAssembly;
        dynamic evaluator = 
            Activator.CreateInstance(assembly.GetType("MyAssembly.Evaluator"));
        return evaluator.Eval();
    }
}
Mechanize answered 13/4, 2015 at 4:50 Comment(3)
is there any way to execute any other commands (instead of just mathematical 2+2), like: string a=MyComplexThings(); System.Windows.Forms.MessageBox.Show(a)Rip
@Rip You could do it by creating a program in C# and running it using Process.Start. It sounds meta but i think you could do it with CodeDomMechanize
well, i might now the generic advise "do it with CodeDom", but that is what i commented, if you had any code-example of that... well thanks anyway.Rip
P
1

It's possible using the System.Reflection.Emit or System.CodeDom namespaces, but it's not exactly a good idea as there's no mechanism to control what namespaces are and are not allowed to be used. You write an eval() expecting simple expressions, and the next thing you know a user is suing you because your code allowed them to enter a string that wiped their hard drive. eval()-like functions are huge gaping security holes and should be avoided.

The preferred alternative in the .Net world is a DSL (domain specific language). If you google around, you can find some pre-created DSL's for common tasks such as arithmetic.

Pillar answered 19/5, 2011 at 1:13 Comment(2)
It isn't possible using Reflection.Emit.Nuncia
Joel, this will be used by me alone just to make it. the security hole wont be a problem. how would i go about doing this?Putup
R
1

Thank you so much Mr.Teoman Soygul

if you want to catch the error then you can use try catch,then we can use that values to future purpose.

try
{
    DataTable table = new System.Data.DataTable();
    table.Columns.Add("expression", string.Empty.GetType(), expression);
    DataRow row = table.NewRow();
    table.Rows.Add(row);
    return double.Parse((string)row["expression"]);
}
catch (Exception)
{
    return -1;
}
Rhinology answered 2/3, 2020 at 12:48 Comment(0)
M
1

I created the ExpressionEvaluatorCs Nuget package inspired by mar.k's answer and also added the option to specify return type.

Sample code

// Returns object 6
object result1 = ExpressionEvaluator.Evaluate("(1 + 2) * 2");

// Returns int 6
int result1 = ExpressionEvaluator.Evaluate<int>("(1 + 2) * 2");

Moritz answered 10/5, 2020 at 1:30 Comment(0)
S
1

Can we do it like this.

var a = Console.ReadLine(); // give string here, ex: "1 + 2"
double result = Convert.ToDouble(new System.Data.DataTable().Compute(a, null));

But i fear, C# DataTable compute do not support Exponent Operator (** or ^).

  • Example: "2^3" -> throws an error.
Subtotal answered 21/9, 2022 at 3:19 Comment(0)
D
-2

There is no native C# eval function; but as others have previously stated, there are several workarounds for what you are trying to do.

If you're interested in evaluating more complicated C# code, my C# eval program provides for evaluating C# code at runtime and supports many C# statements. In fact, this code is usable within any .NET project, however, it is limited to using C# syntax. Have a look at my website, http://csharp-eval.com, for additional details.

Danish answered 10/6, 2011 at 2:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.