JavaScript 有 eval() 直接執行字串運算式,C# 能做到嗎?答案是肯定的。透過 System.CodeDom.Compiler 與反射,可在執行時動態編譯並執行 C# 程式碼片段。
using System;
using System.Text;
using System.CodeDom.Compiler;
using System.Reflection;
using System.IO;
using Microsoft.CSharp;
namespace CoustomEval
{
public class MyEval
{
public object Eval(string cSharpCode)
{
var provider = new CSharpCodeProvider();
var compiler = provider.CreateCompiler();
var parameters = new CompilerParameters
{
ReferencedAssemblies = { "system.dll" },
CompilerOptions = "/t:library",
GenerateInMemory = true
};
var code = new StringBuilder();
code.AppendLine("using System;");
code.AppendLine("namespace CoustomEval {");
code.AppendLine(" public class MyLib {");
code.AppendLine(" private " + cSharpCode); // 例如:int i = 10;
code.AppendLine(" public int MyMethod() { return i; }");
code.AppendLine(" }");
code.AppendLine("}");
var results = compiler.CompileAssemblyFromSource(parameters, code.ToString());
var assembly = results.CompiledAssembly;
var instance = assembly.CreateInstance("CoustomEval.MyLib");
var method = instance.GetType().GetMethod("MyMethod");
return method.Invoke(instance, null);
}
}
}
private void btnCalculate_Click(object sender, EventArgs e)
{
var eval = new MyEval();
object result = eval.Eval(txtExpression.Text); // 輸入:int i = 10;
txtResult.Text = result.ToString(); // 顯示:10
}
| 輸入運算式 | 輸出結果 |
|---|---|
int i = 10; | 10 |
int x = 5; int y = 3; int z = x * y + 2; | 17 |
double r = Math.Sqrt(16); | 4 |
GenerateInMemory=true 避免產生實體 DLL 檔案。CreateInstance → GetMethod → Invoke 完整鏈路。Microsoft.CodeAnalysis.CSharp.Scripting) 或 Expression Trees 獲得更好效能與安全性。System.Math, System.Linq 等)