我們在寫JavaScript程式的時候,有一個函數很有趣,eval(),這個方法非常有趣,他可以編譯他內部的字元串,並將字元串按照JS代碼執行,例如eval(‘alert(“message”)’),執行的結果就是彈窗列印出message這個信息。如下圖 最近我在用C#寫一個功能的時候的時候也遇到相似 ...
我們在寫JavaScript程式的時候,有一個函數很有趣,eval(),這個方法非常有趣,他可以編譯他內部的字元串,並將字元串按照JS代碼執行,例如eval(‘alert(“message”)’),執行的結果就是彈窗列印出message這個信息。如下圖
最近我在用C#寫一個功能的時候的時候也遇到相似的需求,我的要求是自定義一個對字元串的驗證代碼,在程式執行的過程中對自定義的代碼進行編譯並執行,最後返回執行的結果。自定義的驗證代碼可以保存在文件中,也可以保存到資料庫中,在需要的時候取出驗證的代碼,並執行。
要執行這樣的功能可以有幾種方案可以實現。
方案一、
通過拼接字元串的方式,生成一個cs類文件,再使用反射的方式調用此cs文件即可,此方式最簡單,只需要熟練使用反射的相關知識即可。
方案二、
使用CSharpCodeProvider對象來解析字元串並通過反射的方式執行。
上面兩種方案都需要熟練使用反射的技術,方案一相對來說比較簡單,這裡主要學習使用方案二來是實現相關功能。
使用方案二需要瞭解以下幾個類。
CSharpCodeProvider, ICodeCompiler, CompilerParameters, CompilerResults
下麵是一個示常式序
//1.創建CSharpCodeProvider的實例
CSharpCodeProvider cs = new CSharpCodeProvider();
//2.創建一個ICodeComplier對象
ICodeCompiler cc = cs.CreateCompiler();
//3.創建一個CompilerParameters的實例
CompilerParameters cp = new CompilerParameters();
cp.GenerateInMemory = true;//設定在記憶體中創建程式集
cp.GenerateExecutable = false;//設定是否創建可執行文件,也就是exe文件或者dll文件
cp.ReferencedAssemblies.Add("System.dll");//此處代碼是添加對應dll文件的引用
cp.ReferencedAssemblies.Add("System.Core.dll");//System.Linq存在於System.Core.dll文件中
//4.創建CompilerResults的實例
string strExpre= "using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace DynamicCompileTest{public class TestClass1{public bool CheckBool(string source){ return source.Contains(\"SC\"); }}}";
CompilerResults cr = cc.CompileAssemblyFromSource(cp, strExpre);
if (cr.Errors.HasErrors)
{
Console.WriteLine(cr.Errors.ToString());
}
else
{
//5.創建一個Assembly對象
Assembly ass = cr.CompiledAssembly;//動態編譯程式集
object obj = ass.CreateInstance("DynamicCompileTest.TestClass1");
MethodInfo mi = obj.GetType().GetMethod("CheckBool");
bool result = (bool)mi.Invoke(obj, new object[] { "LYF" });
}
Console.ReadKey();
總體來說,兩個方案都是通過拼接字元串最後形成可執行的代碼來實現的,與我們平時在VS中寫代碼的方式相同。