这篇文章主要介绍了C# 实现Eval(字符串表达式)的三种方法,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
一、背景
假如给定一个字符串表达式"-12 * ( - 2.2 + 7.7 ) - 44 * 2"
,让你计算结果,熟悉JavaScript的都知道有个Eval
函数可以直接进行计算,而C#中却没有这个函数,下面提供三种实现方式
二、代码
public class Class1
{
#region 方法一:利用CodeCom
[Obsolete]
System.CodeDom.Compiler.ICodeCompiler comp = new Microsoft.CSharp.CSharpCodeProvider().CreateCompiler();
System.CodeDom.Compiler.CompilerParameters cp = new System.CodeDom.Compiler.CompilerParameters();
public object Eval_1(string Expression)
{
StringBuilder code = new StringBuilder();
code.Append("using System; \n");
code.Append("namespace ADOGuy { \n");
code.Append(" public class _Evaluator { \n");
code.Append(" public object __foo() ");
code.Append("{ ");
code.AppendFormat(" return ({0}); ", Expression);
code.Append("}\n");
code.Append("} }");
System.CodeDom.Compiler.CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString());
System.Reflection.Assembly a = cr.CompiledAssembly;
object _Compiled = a.CreateInstance("ADOGuy._Evaluator");
System.Reflection.MethodInfo mi = _Compiled.GetType().GetMethod("__foo");
return mi.Invoke(_Compiled, null);
}
#endregion
#region 方法二:对表达式分析
string Precede(string p, string q)
{
switch (p)
{
case "+":
case "-":
return ("*/(".IndexOf(q) != -1) ? "<" : ">";
case "*":
case "/":
return (q == "(") ? "<" : ">";
case "(":
return (q == ")") ? "=" : "<";
case ")":
return (q == "(") ? "?" : ">";
case "#":
return (q == "#") ? "=" : "<";
}
return "?";
}
Double Operate(Double a, char o, Double b)
{
switch (o)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
}
return 0;
}
public Object Eval_2(string Expression)
{
Stack nArr = new Stack(), oArr = new Stack();
int j = 0;
Double a = 0, b = 0;
string w = "";
char o;
MatchCollection arr = Regex.Matches(Expression.Replace(" ", "") + "#", @"(((?<=(^|\())-)?\d+(\.\d+)?|\D)");
oArr.Push('#');
w = Convert.ToString(arr[j++]);
while (!(w == "#" && Convert.ToString(oArr.Peek()) == "#"))
{
if ("+-*/()#".IndexOf(w) != -1)
{
switch (Precede(oArr.Peek().ToString(), w))
{
case "<":
oArr.Push(w);
w = Convert.ToString(arr[j++]);
break;
case "=":
oArr.Pop();
w = Convert.ToString(arr[j++]);
break;
case ">":
o = Convert.ToChar(oArr.Pop());
b = Convert.ToDouble(nArr.Pop());
a = Convert.ToDouble(nArr.Pop());
nArr.Push(Operate(a, o, b));
break;
default:
return "Error";
}
}
else
{
nArr.Push(w);
w = Convert.ToString(arr[j++]);
}
}
return nArr.Pop();
}
#endregion
#region 方法三:利用JScript的Eval
//需要引用Microsoft.JScript
[Obsolete]
readonly Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
[Obsolete]
public object Eval_3(string Expression)
{
return Microsoft.JScript.Eval.JScriptEvaluate(Expression, ve);
}
#endregion
}
三、测试
static void Main(string[] args)
{
String strExpression = "-12 * ( - 2.2 + 7.7 ) - 44 * 2";
var obj = new Class1();
Console.WriteLine($"方法一(CodeCom法)计算结果:{obj.Eval_1(strExpression)}");
Console.WriteLine($"方法二(分析法)计算结果:{obj.Eval_2(strExpression)}");
Console.WriteLine($"方法三(JScript法)计算结果:{obj.Eval_3(strExpression)}");
Console.ReadLine();
}
运行结果:
方法一(CodeCom法)计算结果:-154
方法二(分析法)计算结果:-154
方法三(JScript法)计算结果:-154
以上就是C# 实现Eval(字符串表达式)的三种方法的详细内容,更多关于C# 实现Eval(字符串表达式)的资料请关注得得之家其它相关文章!
沃梦达教程
本文标题为:C# 实现Eval(字符串表达式)的三种方法
基础教程推荐
猜你喜欢
- 一个读写csv文件的C#类 2022-11-06
- unity实现动态排行榜 2023-04-27
- C#控制台实现飞行棋小游戏 2023-04-22
- linux – 如何在Debian Jessie中安装dotnet core sdk 2023-09-26
- C# List实现行转列的通用方案 2022-11-02
- ZooKeeper的安装及部署教程 2023-01-22
- C# 调用WebService的方法 2023-03-09
- C#类和结构详解 2023-05-30
- C# windows语音识别与朗读实例 2023-04-27
- winform把Office转成PDF文件 2023-06-14