執行C#動態代碼


執行C#動態代碼

  1 using System;
  2 using System.Data;
  3 using System.Configuration;
  4 using System.Text;
  5 using System.CodeDom.Compiler;
  6 using Microsoft.CSharp;
  7 using System.Reflection;
  8 
  9 namespace EvalGuy
 10 {
 11     /// <summary>   
 12     /// 本類用來將字符串轉為可執行文本並執行   
 13     /// 從別處復制,勿隨意更改!   
 14     /// </summary>   
 15     public class Evaluator
 16     {
 17         #region 構造函數   
 18         /// <summary>   
 19         /// 可執行串的構造函數   
 20         /// </summary>   
 21         /// <param name="items">   
 22         /// 可執行字符串數組   
 23         /// </param>   
 24         public Evaluator(EvaluatorItem[] items)
 25         {
 26             ConstructEvaluator(items);      //調用解析字符串構造函數進行解析   
 27         }
 28         /// <summary>   
 29         /// 可執行串的構造函數   
 30         /// </summary>   
 31         /// <param name="returnType">返回值類型</param>   
 32         /// <param name="expression">執行表達式</param>   
 33         /// <param name="name">執行字符串名稱</param>   
 34         public Evaluator(Type returnType, string expression, string name)
 35         {
 36             //創建可執行字符串數組   
 37             EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) };
 38             ConstructEvaluator(items);      //調用解析字符串構造函數進行解析   
 39         }
 40         /// <summary>   
 41         /// 可執行串的構造函數   
 42         /// </summary>   
 43         /// <param name="item">可執行字符串項</param>   
 44         public Evaluator(EvaluatorItem item)
 45         {
 46             EvaluatorItem[] items = { item };//將可執行字符串項轉為可執行字符串項數組   
 47             ConstructEvaluator(items);      //調用解析字符串構造函數進行解析   
 48         }
 49         /// <summary>   
 50         /// 解析字符串構造函數   
 51         /// </summary>   
 52         /// <param name="items">待解析字符串數組</param>   
 53         private void ConstructEvaluator(EvaluatorItem[] items)
 54         {
 55             //創建C#編譯器實例   
 56             ICodeCompiler comp = (new CSharpCodeProvider().CreateCompiler());
 57             //編譯器的傳入參數   
 58             CompilerParameters cp = new CompilerParameters();
 59 
 60             cp.ReferencedAssemblies.Add("system.dll");              //添加程序集 system.dll 的引用   
 61             cp.ReferencedAssemblies.Add("system.data.dll");         //添加程序集 system.data.dll 的引用   
 62             cp.ReferencedAssemblies.Add("system.xml.dll");          //添加程序集 system.xml.dll 的引用   
 63             cp.GenerateExecutable = false;                          //不生成可執行文件   
 64             cp.GenerateInMemory = true;                             //在內存中運行   
 65 
 66             StringBuilder code = new StringBuilder();               //創建代碼串   
 67                                                                     /* 
 68                                                                      * 添加常見且必須的引用字符串 
 69                                                                      */
 70             code.Append("using System; \n");
 71             code.Append("using System.Data; \n");
 72             code.Append("using System.Data.SqlClient; \n");
 73             code.Append("using System.Data.OleDb; \n");
 74             code.Append("using System.Xml; \n");
 75 
 76             code.Append("namespace EvalGuy { \n");                  //生成代碼的命名空間為EvalGuy,和本代碼一樣   
 77 
 78             code.Append(" public class _Evaluator { \n");          //產生 _Evaluator 類,所有可執行代碼均在此類中運行   
 79             foreach (EvaluatorItem item in items)               //遍歷每一個可執行字符串項   
 80             {
 81                 code.AppendFormat("    public {0} {1}() ",          //添加定義公共函數代碼   
 82                                   item.ReturnType.Name,             //函數返回值為可執行字符串項中定義的返回值類型   
 83                                   item.Name);                       //函數名稱為可執行字符串項中定義的執行字符串名稱   
 84                 code.Append("{ ");                                  //添加函數開始括號   
 85                 code.AppendFormat("return ({0});", item.Expression);//添加函數體,返回可執行字符串項中定義的表達式的值   
 86                 code.Append("}\n");                                 //添加函數結束括號   
 87             }
 88             code.Append("} }");                                 //添加類結束和命名空間結束括號   
 89 
 90             //得到編譯器實例的返回結果   
 91             CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString());
 92 
 93             if (cr.Errors.HasErrors)                            //如果有錯誤   
 94             {
 95                 StringBuilder error = new StringBuilder();          //創建錯誤信息字符串   
 96                 error.Append("編譯有錯誤的表達式: ");                //添加錯誤文本   
 97                 foreach (CompilerError err in cr.Errors)            //遍歷每一個出現的編譯錯誤   
 98                 {
 99                     error.AppendFormat("{0}\n", err.ErrorText);     //添加進錯誤文本,每個錯誤后換行   
100                 }
101                 throw new Exception("編譯錯誤: " + error.ToString());//拋出異常   
102             }
103             Assembly a = cr.CompiledAssembly;                       //獲取編譯器實例的程序集   
104             _Compiled = a.CreateInstance("EvalGuy._Evaluator");     //通過程序集查找並聲明 EvalGuy._Evaluator 的實例   
105         }
106         #endregion
107 
108         #region 公有成員   
109         /// <summary>   
110         /// 執行字符串並返回整型值   
111         /// </summary>   
112         /// <param name="name">執行字符串名稱</param>   
113         /// <returns>執行結果</returns>   
114         public int EvaluateInt(string name)
115         {
116             return (int)Evaluate(name);
117         }
118         /// <summary>   
119         /// 執行字符串並返回字符串型值   
120         /// </summary>   
121         /// <param name="name">執行字符串名稱</param>   
122         /// <returns>執行結果</returns>   
123         public string EvaluateString(string name)
124         {
125             return (string)Evaluate(name);
126         }
127         /// <summary>   
128         /// 執行字符串並返回布爾型值   
129         /// </summary>   
130         /// <param name="name">執行字符串名稱</param>   
131         /// <returns>執行結果</returns>   
132         public bool EvaluateBool(string name)
133         {
134             return (bool)Evaluate(name);
135         }
136         /// <summary>   
137         /// 執行字符串並返 object 型值   
138         /// </summary>   
139         /// <param name="name">執行字符串名稱</param>   
140         /// <returns>執行結果</returns>   
141         public object Evaluate(string name)
142         {
143             MethodInfo mi = _Compiled.GetType().GetMethod(name);//獲取 _Compiled 所屬類型中名稱為 name 的方法的引用   
144             return mi.Invoke(_Compiled, null);                  //執行 mi 所引用的方法   
145         }
146         #endregion
147 
148         #region 靜態成員   
149         /// <summary>   
150         /// 執行表達式並返回整型值   
151         /// </summary>   
152         /// <param name="code">要執行的表達式</param>   
153         /// <returns>運算結果</returns>   
154         static public int EvaluateToInteger(string code)
155         {
156             Evaluator eval = new Evaluator(typeof(int), code, staticMethodName);//生成 Evaluator 類的對像   
157             return (int)eval.Evaluate(staticMethodName);                        //執行並返回整型數據   
158         }
159         /// <summary>   
160         /// 執行表達式並返回字符串型值   
161         /// </summary>   
162         /// <param name="code">要執行的表達式</param>   
163         /// <returns>運算結果</returns>   
164         static public string EvaluateToString(string code)
165         {
166             Evaluator eval = new Evaluator(typeof(string), code, staticMethodName);//生成 Evaluator 類的對像   
167             return (string)eval.Evaluate(staticMethodName);                     //執行並返回字符串型數據   
168         }
169         /// <summary>   
170         /// 執行表達式並返回布爾型值   
171         /// </summary>   
172         /// <param name="code">要執行的表達式</param>   
173         /// <returns>運算結果</returns>   
174         static public bool EvaluateToBool(string code)
175         {
176             Evaluator eval = new Evaluator(typeof(bool), code, staticMethodName);//生成 Evaluator 類的對像   
177             return (bool)eval.Evaluate(staticMethodName);                       //執行並返回布爾型數據   
178         }
179         /// <summary>   
180         /// 執行表達式並返回 object 型值   
181         /// </summary>   
182         /// <param name="code">要執行的表達式</param>   
183         /// <returns>運算結果</returns>   
184         static public object EvaluateToObject(string code)
185         {
186             Evaluator eval = new Evaluator(typeof(object), code, staticMethodName);//生成 Evaluator 類的對像   
187             return eval.Evaluate(staticMethodName);                             //執行並返回 object 型數據   
188         }
189         #endregion
190 
191         #region 私有成員   
192         /// <summary>   
193         /// 靜態方法的執行字符串名稱   
194         /// </summary>   
195         private const string staticMethodName = "__foo";
196         /// <summary>   
197         /// 用於動態引用生成的類,執行其內部包含的可執行字符串   
198         /// </summary>   
199         object _Compiled = null;
200         #endregion
201     }
202     /// <summary>   
203     /// 可執行字符串項(即一條可執行字符串)   
204     /// </summary>   
205     public class EvaluatorItem
206     {
207         /// <summary>   
208         /// 返回值類型   
209         /// </summary>   
210         public Type ReturnType;
211         /// <summary>   
212         /// 執行表達式   
213         /// </summary>   
214         public string Expression;
215         /// <summary>   
216         /// 執行字符串名稱   
217         /// </summary>   
218         public string Name;
219         /// <summary>   
220         /// 可執行字符串項構造函數   
221         /// </summary>   
222         /// <param name="returnType">返回值類型</param>   
223         /// <param name="expression">執行表達式</param>   
224         /// <param name="name">執行字符串名稱</param>   
225         public EvaluatorItem(Type returnType, string expression, string name)
226         {
227             ReturnType = returnType;
228             Expression = expression;
229             Name = name;
230         }
231     }
232 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM