用来将字符串转为可执行文本并执行
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 }