执行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     ///    
 12     /// 本类用来将字符串转为可执行文本并执行   
 13     /// 从别处复制,勿随意更改!   
 14     ///    
 15     public class Evaluator
 16     {
 17         #region 构造函数   
 18         ///    
 19         /// 可执行串的构造函数   
 20         ///    
 21         ///    
 22         /// 可执行字符串数组   
 23         ///    
 24         public Evaluator(EvaluatorItem[] items)
 25         {
 26             ConstructEvaluator(items);      //调用解析字符串构造函数进行解析   
 27         }
 28         ///    
 29         /// 可执行串的构造函数   
 30         ///    
 31         /// 返回值类型   
 32         /// 执行表达式   
 33         /// 执行字符串名称   
 34         public Evaluator(Type returnType, string expression, string name)
 35         {
 36             //创建可执行字符串数组   
 37             EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) };
 38             ConstructEvaluator(items);      //调用解析字符串构造函数进行解析   
 39         }
 40         ///    
 41         /// 可执行串的构造函数   
 42         ///    
 43         /// 可执行字符串项   
 44         public Evaluator(EvaluatorItem item)
 45         {
 46             EvaluatorItem[] items = { item };//将可执行字符串项转为可执行字符串项数组   
 47             ConstructEvaluator(items);      //调用解析字符串构造函数进行解析   
 48         }
 49         ///    
 50         /// 解析字符串构造函数   
 51         ///    
 52         /// 待解析字符串数组   
 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         ///    
110         /// 执行字符串并返回整型值   
111         ///    
112         /// 执行字符串名称   
113         /// 执行结果   
114         public int EvaluateInt(string name)
115         {
116             return (int)Evaluate(name);
117         }
118         ///    
119         /// 执行字符串并返回字符串型值   
120         ///    
121         /// 执行字符串名称   
122         /// 执行结果   
123         public string EvaluateString(string name)
124         {
125             return (string)Evaluate(name);
126         }
127         ///    
128         /// 执行字符串并返回布尔型值   
129         ///    
130         /// 执行字符串名称   
131         /// 执行结果   
132         public bool EvaluateBool(string name)
133         {
134             return (bool)Evaluate(name);
135         }
136         ///    
137         /// 执行字符串并返 object 型值   
138         ///    
139         /// 执行字符串名称   
140         /// 执行结果   
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         ///    
150         /// 执行表达式并返回整型值   
151         ///    
152         /// 要执行的表达式   
153         /// 运算结果   
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         ///    
160         /// 执行表达式并返回字符串型值   
161         ///    
162         /// 要执行的表达式   
163         /// 运算结果   
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         ///    
170         /// 执行表达式并返回布尔型值   
171         ///    
172         /// 要执行的表达式   
173         /// 运算结果   
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         ///    
180         /// 执行表达式并返回 object 型值   
181         ///    
182         /// 要执行的表达式   
183         /// 运算结果   
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         ///    
193         /// 静态方法的执行字符串名称   
194         ///    
195         private const string staticMethodName = "__foo";
196         ///    
197         /// 用于动态引用生成的类,执行其内部包含的可执行字符串   
198         ///    
199         object _Compiled = null;
200         #endregion
201     }
202     ///    
203     /// 可执行字符串项(即一条可执行字符串)   
204     ///    
205     public class EvaluatorItem
206     {
207         ///    
208         /// 返回值类型   
209         ///    
210         public Type ReturnType;
211         ///    
212         /// 执行表达式   
213         ///    
214         public string Expression;
215         ///    
216         /// 执行字符串名称   
217         ///    
218         public string Name;
219         ///    
220         /// 可执行字符串项构造函数   
221         ///    
222         /// 返回值类型   
223         /// 执行表达式   
224         /// 执行字符串名称   
225         public EvaluatorItem(Type returnType, string expression, string name)
226         {
227             ReturnType = returnType;
228             Expression = expression;
229             Name = name;
230         }
231     }
232 }
View Code

 

你可能感兴趣的:(执行C#动态代码)