C#中是否有求值函数?

C#中是否有求值函数?,c#,eval,language-features,C#,Eval,Language Features,我在一个文本框中输入一个等式,它将生成给定抛物线的图形。是否可以使用评估功能?我使用的是C#2010,它没有Microsoft。JScriptC#没有类似的求值函数,但创建一个求值函数非常简单: public static double Evaluate(string expression) { System.Data.DataTable table = new System.Data.DataTable(); table.C

我在一个文本框中输入一个等式,它将生成给定抛物线的图形。是否可以使用评估功能?我使用的是C#2010,它没有Microsoft。JScript

C#没有类似的求值函数,但创建一个求值函数非常简单:

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"]);  
       }
现在简单地这样称呼它:

Console.WriteLine(Evaluate("9 + 5"));

可以使用System.Reflection.Emit或System.CodeDom名称空间,但这并不是一个好主意,因为没有机制来控制哪些名称空间是不允许使用的。您编写了一个eval(),期望得到简单的表达式,然后您知道的下一件事是用户起诉您,因为您的代码允许他们输入一个字符串,该字符串擦除了他们的硬盘
eval()
-类函数是巨大的安全漏洞,应该避免

在.Net世界中,首选的替代方案是。如果你四处搜索,你可以找到一些预先创建的DSL,用于算术等常见任务。

没有本机的C#eval函数;但是正如其他人之前所说的,对于您正在尝试做的事情,有几种变通方法


如果您对评估更复杂的C#代码感兴趣,我的C#eval程序提供在运行时评估C#代码,并支持许多C#语句。事实上,这段代码在任何.NET项目中都是可用的,但是,它仅限于使用C#语法。查看我的网站,了解更多详细信息。

您可以使用DataTable类的“Compute”方法轻松完成此操作

static Double Eval(String expression)
{
    System.Data.DataTable table = new System.Data.DataTable();
    return Convert.ToDouble(table.Compute(expression, String.Empty));
}
将字符串形式的项传递给函数以获得结果

Double result = Eval("7 * 6");
result = Eval("17 + 4");
...

您可以使用CodeDom自己创建一个。它会很慢,因为每次调用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();
    }
}

非常感谢Teoman Soygul先生

如果您想捕获错误,那么可以使用try-catch,然后我们可以将该值用于将来的用途

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;
}
我根据mar.k的答案创建了Nuget包,还添加了指定返回类型的选项

示例代码

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

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

//返回对象6
objectresult1=ExpressionEvaluator.Evaluate(“(1+2)*2”);
//返回整数6
int result1=表达式评估器。评估(“(1+2)*2”);

Wow。这真是鬼鬼祟祟的=)如果你用它来绘制图表,它的一个变体可以用来生成函数值。在DataTable中有一列名为“x”,将f(x)的表达式放在另一列中?注意,这只计算非常简单的数学表达式。为了获得更好的性能,您可以将datatable保留在函数之外。因为这只计算非常简单,我正在寻找一些东西来计算ax^2+bx+c有什么办法吗?如果允许您使用第三方库,请使用它。使用Reflection.Emit.Joel是不可能的,我将单独使用它来实现它。安全漏洞不会是问题。我该怎么做呢?+1。此外,必须包括使用System.Data的
,并且必须为
System.Data
添加程序集参考。这将不支持任何第三级运算符,如13.67113<8?28.336489999998:13.67113有没有办法执行任何其他命令(而不仅仅是数学上的2+2),比如:
string a=MyComplexThings();System.Windows.Forms.MessageBox.Show(a)
@T.Todua您可以通过在C#中创建一个程序并使用Process.Start运行它来实现。这听起来像是元代码,但我认为你可以用CodeDomwell来做,我现在可能会建议“用CodeDom来做”,但这就是我的评论,如果你有任何这样的代码示例的话。。。无论如何,谢谢你。