用来将字符串转为可执行文本并执行

  1 /// <summary>
  2 /// 本类用来将字符串转为可执行文本并执行
  3 /// 做了一部分修改,修改原来的错误,修改,增加了部分逻辑。测试通过,请勿随意修改 ZhangQC
  4 /// </summary>
  5 public class Evaluator
  6 {
  7 #region 构造函数
  8 /// <summary>
  9 /// 可执行串的构造函数
 10 /// </summary>
 11 /// <param name="items">
 12 /// 可执行字符串数组
 13 /// </param>
 14 public Evaluator(EvaluatorItem[] items)
 15 {
 16 ConstructEvaluator(items); //调用解析字符串构造函数进行解析
 17 }
 18 /// <summary>
 19 /// 可执行串的构造函数
 20 /// </summary>
 21 /// <param name="returnType">返回值类型</param>
 22 /// <param name="expression">执行表达式</param>
 23 /// <param name="name">执行字符串名称</param>
 24 public Evaluator(Type returnType, string expression, string name)
 25 {
 26 //创建可执行字符串数组
 27 EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) };
 28 ConstructEvaluator(items); //调用解析字符串构造函数进行解析
 29 }
 30 /// <summary>
 31 /// 可执行串的构造函数
 32 /// </summary>
 33 /// <param name="item">可执行字符串项</param>
 34 public Evaluator(EvaluatorItem item)
 35 {
 36 EvaluatorItem[] items = { item };//将可执行字符串项转为可执行字符串项数组
 37 ConstructEvaluator(items); //调用解析字符串构造函数进行解析
 38 }
 39 
 40 /// <summary>
 41 /// 解析字符串构造函数
 42 /// </summary>
 43 /// <param name="items">待解析字符串数组</param>
 44 /// <param name="isReturn">这个表示,你的字符串中是否需要在上return,false表示你不需要加,true代表你需要加上return</param>
 45 private void ConstructEvaluator(EvaluatorItem[] items,bool isReturn=false)
 46 {
 47 //创建C#编译器实例
 48 #pragma warning disable 618
 49 ICodeCompiler comp = (new CSharpCodeProvider().CreateCompiler());
 50 #pragma warning restore 618
 51 //编译器的传入参数
 52 CompilerParameters cp = new CompilerParameters();
 53 cp.ReferencedAssemblies.Add("system.dll"); //添加程序集 system.dll 的引用
 54 cp.ReferencedAssemblies.Add("system.data.dll"); //添加程序集 system.data.dll 的引用
 55 cp.ReferencedAssemblies.Add("system.xml.dll"); //添加程序集 system.xml.dll 的引用
 56 cp.GenerateExecutable = false; //不生成可执行文件
 57 cp.GenerateInMemory = true; //在内存中运行
 58 StringBuilder code = new StringBuilder(); //创建代码串
 59 /*
 60 * 添加常见且必须的引用字符串
 61 */
 62 code.Append("using System; \n");
 63 code.Append("using System.Data; \n");
 64 code.Append("using System.Data.SqlClient; \n");
 65 code.Append("using System.Data.OleDb; \n");
 66 code.Append("using System.Xml; \n");
 67 code.Append("namespace ESIC.RFQ.Common.EvaluatorExtend { \n"); //生成代码的命名空间为ESIC.RFQ.Common.EvaluatorExtend,和本代码一样
 68 code.Append(" public class _Evaluator { \n"); //产生 _Evaluator 类,所有可执行代码均在此类中运行
 69 foreach (EvaluatorItem item in items) //遍历每一个可执行字符串项
 70 {
 71 code.AppendFormat(" public {0} {1}() ", //添加定义公共函数代码
 72 item.ReturnType.Name, //函数返回值为可执行字符串项中定义的返回值类型
 73 item.Name); //函数名称为可执行字符串项中定义的执行字符串名称
 74 code.Append("{ "); //添加函数开始括号
 75 code.AppendFormat(isReturn ? "{0}" : "return ({0});", item.Expression);
 76 code.Append("}\n"); //添加函数结束括号
 77 }
 78 code.Append("} }"); //添加类结束和命名空间结束括号
 79 //得到编译器实例的返回结果
 80 CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString());
 81 if (cr.Errors.HasErrors) //如果有错误
 82 {
 83 StringBuilder error = new StringBuilder(); //创建错误信息字符串
 84 error.Append("编译有错误的表达式: "); //添加错误文本
 85 foreach (CompilerError err in cr.Errors) //遍历每一个出现的编译错误
 86 {
 87 error.AppendFormat("{0}/n", err.ErrorText); //添加进错误文本,每个错误后换行
 88 }
 89 throw new Exception("编译错误: " + error);//抛出异常
 90 }
 91 Assembly a = cr.CompiledAssembly; //获取编译器实例的程序集
 92 _compiled = a.CreateInstance("ESIC.RFQ.Common.EvaluatorExtend._Evaluator"); //通过程序集查找并声明 ESIC.RFQ.Common.EvaluatorExtend._Evaluator 的实例
 93 }
 94 #endregion
 95 #region 公有成员
 96 /// <summary>
 97 /// 执行字符串并返回整型值
 98 /// </summary>
 99 /// <param name="name">执行字符串名称</param>
100 /// <returns>执行结果</returns>
101 public int EvaluateInt(string name)
102 {
103 return (int)Evaluate(name);
104 }
105 /// <summary>
106 /// 执行字符串并返回字符串型值
107 /// </summary>
108 /// <param name="name">执行字符串名称</param>
109 /// <returns>执行结果</returns>
110 public string EvaluateString(string name)
111 {
112 return (string)Evaluate(name);
113 }
114 /// <summary>
115 /// 执行字符串并返回布尔型值
116 /// </summary>
117 /// <param name="name">执行字符串名称</param>
118 /// <returns>执行结果</returns>
119 public bool EvaluateBool(string name)
120 {
121 return (bool)Evaluate(name);
122 }
123 /// <summary>
124 /// 执行字符串并返 object 型值
125 /// </summary>
126 /// <param name="name">执行字符串名称</param>
127 /// <returns>执行结果</returns>
128 public object Evaluate(string name)
129 {
130 MethodInfo mi = _compiled.GetType().GetMethod(name);//获取 _Compiled 所属类型中名称为 name 的方法的引用
131 return mi.Invoke(_compiled, null); //执行 mi 所引用的方法
132 }
133 #endregion
134 #region 静态成员
135 /// <summary>
136 /// 执行表达式并返回整型值
137 /// </summary>
138 /// <param name="code">要执行的表达式</param>
139 /// <returns>运算结果</returns>
140 public static int EvaluateToInteger(string code)
141 {
142 Evaluator eval = new Evaluator(typeof(int), code, StaticMethodName);//生成 Evaluator 类的对像
143 return (int)eval.Evaluate(StaticMethodName); //执行并返回整型数据
144 }
145 /// <summary>
146 /// 执行表达式并返回字符串型值
147 /// </summary>
148 /// <param name="code">要执行的表达式</param>
149 /// <returns>运算结果</returns>
150 public static string EvaluateToString(string code)
151 {
152 Evaluator eval = new Evaluator(typeof(string), code, StaticMethodName);//生成 Evaluator 类的对像
153 return (string)eval.Evaluate(StaticMethodName); //执行并返回字符串型数据
154 }
155 /// <summary>
156 /// 执行表达式并返回布尔型值
157 /// </summary>
158 /// <param name="code">要执行的表达式</param>
159 /// <returns>运算结果</returns>
160 public static bool EvaluateToBool(string code)
161 {
162 Evaluator eval = new Evaluator(typeof(bool), code, StaticMethodName);//生成 Evaluator 类的对像
163 return (bool)eval.Evaluate(StaticMethodName); //执行并返回布尔型数据
164 }
165 /// <summary>
166 /// 执行表达式并返回 object 型值
167 /// </summary>
168 /// <param name="code">要执行的表达式</param>
169 /// <returns>运算结果</returns>
170 public static object EvaluateToObject(string code)
171 {
172 Evaluator eval = new Evaluator(typeof(object), code, StaticMethodName);//生成 Evaluator 类的对像
173 return eval.Evaluate(StaticMethodName); //执行并返回 object 型数据
174 }
175 #endregion
176 #region 私有成员
177 /// <summary>
178 /// 静态方法的执行字符串名称
179 /// </summary>
180 private const string StaticMethodName = "__foo";
181 /// <summary>
182 /// 用于动态引用生成的类,执行其内部包含的可执行字符串
183 /// </summary>
184 object _compiled = null;
185 #endregion
186 }
187 
188 
189 /// <summary>
190 /// 可执行字符串项(即一条可执行字符串)
191 /// </summary>
192 public class EvaluatorItem
193 {
194 /// <summary>
195 /// 返回值类型
196 /// </summary>
197 public Type ReturnType;
198 /// <summary>
199 /// 执行表达式
200 /// </summary>
201 public string Expression;
202 /// <summary>
203 /// 执行字符串名称
204 /// </summary>
205 public string Name;
206 /// <summary>
207 /// 可执行字符串项构造函数
208 /// </summary>
209 /// <param name="returnType">返回值类型</param>
210 /// <param name="expression">执行表达式</param>
211 /// <param name="name">执行字符串名称</param>
212 public EvaluatorItem(Type returnType, string expression, string name)
213 {
214 ReturnType = returnType;
215 Expression = expression;
216 Name = name;
217 }
218 }

 

posted @ 2017-01-20 10:20  小小的菜鸟程序员  阅读(1943)  评论(0编辑  收藏  举报