在C#中是否有一个评估函数?

问题描述 投票:10回答:6

我正在将一个方程式输入到TextBox中,该方程式将生成给定抛物线的图形。可以使用eval函数吗?我正在使用C#2010,但没有Microsoft.JScript

c# eval language-features
6个回答
26
投票

C#没有类似的Eval函数,但是创建一个函数确实很容易:

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"));

7
投票

您可以使用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");
...

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();
    }
}

1
投票

可以使用System.Reflection.Emit或System.CodeDom命名空间,但这并不是一个好主意,因为没有机制来控制使用什么名称空间和不允许使用什么名称空间。您编写的eval()需要简单的表达式,然后您知道用户正在起诉您,这是因为您的代码允许他们输入擦除硬盘的字符串。类似eval()的功能是巨大的安全漏洞,应避免使用。

。Net世界中的首选替代方案是DSL (domain specific language)。如果您四处搜寻,可以找到一些用于常见任务(例如算术)的预先创建的DSL。


0
投票

没有本地C#评估函数;但是正如其他人之前所说的,您正在尝试执行多种变通办法。

如果您想评估更复杂的C#代码,我的C#eval程序可在运行时评估C#代码,并支持许多C#语句。实际上,此代码可在任何.NET项目中使用,但是仅限于使用C#语法。请查看我的网站http://csharp-eval.com,以获取更多详细信息。


0
投票

非常感谢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;
}
© www.soinside.com 2019 - 2024. All rights reserved.