C# 實(shí)現(xiàn)Eval(字符串表達(dá)式)的三種方法
一、背景
假如給定一個(gè)字符串表達(dá)式"-12 * ( - 2.2 + 7.7 ) - 44 * 2",讓你計(jì)算結(jié)果,熟悉JavaScript的都知道有個(gè)Eval函數(shù)可以直接進(jìn)行計(jì)算,而C#中卻沒有這個(gè)函數(shù),下面提供三種實(shí)現(xiàn)方式
二、代碼
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 方法二:對(duì)表達(dá)式分析
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
}
三、測(cè)試
static void Main(string[] args)
{
String strExpression = "-12 * ( - 2.2 + 7.7 ) - 44 * 2";
var obj = new Class1();
Console.WriteLine($"方法一(CodeCom法)計(jì)算結(jié)果:{obj.Eval_1(strExpression)}");
Console.WriteLine($"方法二(分析法)計(jì)算結(jié)果:{obj.Eval_2(strExpression)}");
Console.WriteLine($"方法三(JScript法)計(jì)算結(jié)果:{obj.Eval_3(strExpression)}");
Console.ReadLine();
}
運(yùn)行結(jié)果:
方法一(CodeCom法)計(jì)算結(jié)果:-154
方法二(分析法)計(jì)算結(jié)果:-154
方法三(JScript法)計(jì)算結(jié)果:-154
以上就是C# 實(shí)現(xiàn)Eval(字符串表達(dá)式)的三種方法的詳細(xì)內(nèi)容,更多關(guān)于C# 實(shí)現(xiàn)Eval(字符串表達(dá)式)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#調(diào)用SQL?Server中有參數(shù)的存儲(chǔ)過程
這篇文章介紹了C#調(diào)用SQL?Server中有參數(shù)存儲(chǔ)過程的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
Unity3d實(shí)現(xiàn)Flappy Bird游戲
這篇文章主要為大家詳細(xì)介紹了Unity3d實(shí)現(xiàn)Flappy Bird游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
WinForm實(shí)現(xiàn)窗體最大化并遮蓋任務(wù)欄的方法
這篇文章主要介紹了WinForm實(shí)現(xiàn)窗體最大化并遮蓋任務(wù)欄的方法,涉及C#實(shí)現(xiàn)WinForm窗體全屏顯示的實(shí)現(xiàn)及調(diào)用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08
C#實(shí)現(xiàn)循環(huán)發(fā)送電腦屏幕截圖
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)循環(huán)發(fā)送電腦屏幕截圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
C#實(shí)現(xiàn)對(duì)字符串中特定詞出現(xiàn)次數(shù)的計(jì)數(shù)過程
LINQ(Language-Integrated Query)是C#和VB.NET中強(qiáng)大的查詢語言,它可以用來查詢集合、SQL數(shù)據(jù)庫(kù)、XML文檔等,在C#中,我們可以使用LINQ來簡(jiǎn)化對(duì)字符串中特定單詞出現(xiàn)次數(shù)的計(jì)數(shù)過程,需要的朋友可以參考下2024-08-08
macOS系統(tǒng)下Vscode的python配置教程
這篇文章主要介紹了macOS系統(tǒng)下Vscode的python配置教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04

