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

  1 /// 
  2 /// 本类用来将字符串转为可执行文本并执行
  3 /// 做了一部分修改,修改原来的错误,修改,增加了部分逻辑。测试通过,请勿随意修改 ZhangQC
  4 /// 
  5 public class Evaluator
  6 {
  7 #region 构造函数
  8 /// 
  9 /// 可执行串的构造函数
 10 /// 
 11 /// 
 12 /// 可执行字符串数组
 13 /// 
 14 public Evaluator(EvaluatorItem[] items)
 15 {
 16 ConstructEvaluator(items); //调用解析字符串构造函数进行解析
 17 }
 18 /// 
 19 /// 可执行串的构造函数
 20 /// 
 21 /// 返回值类型
 22 /// 执行表达式
 23 /// 执行字符串名称
 24 public Evaluator(Type returnType, string expression, string name)
 25 {
 26 //创建可执行字符串数组
 27 EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) };
 28 ConstructEvaluator(items); //调用解析字符串构造函数进行解析
 29 }
 30 /// 
 31 /// 可执行串的构造函数
 32 /// 
 33 /// 可执行字符串项
 34 public Evaluator(EvaluatorItem item)
 35 {
 36 EvaluatorItem[] items = { item };//将可执行字符串项转为可执行字符串项数组
 37 ConstructEvaluator(items); //调用解析字符串构造函数进行解析
 38 }
 39 
 40 /// 
 41 /// 解析字符串构造函数
 42 /// 
 43 /// 待解析字符串数组
 44 /// 这个表示,你的字符串中是否需要在上return,false表示你不需要加,true代表你需要加上return
 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 /// 
 97 /// 执行字符串并返回整型值
 98 /// 
 99 /// 执行字符串名称
100 /// 执行结果
101 public int EvaluateInt(string name)
102 {
103 return (int)Evaluate(name);
104 }
105 /// 
106 /// 执行字符串并返回字符串型值
107 /// 
108 /// 执行字符串名称
109 /// 执行结果
110 public string EvaluateString(string name)
111 {
112 return (string)Evaluate(name);
113 }
114 /// 
115 /// 执行字符串并返回布尔型值
116 /// 
117 /// 执行字符串名称
118 /// 执行结果
119 public bool EvaluateBool(string name)
120 {
121 return (bool)Evaluate(name);
122 }
123 /// 
124 /// 执行字符串并返 object 型值
125 /// 
126 /// 执行字符串名称
127 /// 执行结果
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 /// 
136 /// 执行表达式并返回整型值
137 /// 
138 /// 要执行的表达式
139 /// 运算结果
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 /// 
146 /// 执行表达式并返回字符串型值
147 /// 
148 /// 要执行的表达式
149 /// 运算结果
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 /// 
156 /// 执行表达式并返回布尔型值
157 /// 
158 /// 要执行的表达式
159 /// 运算结果
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 /// 
166 /// 执行表达式并返回 object 型值
167 /// 
168 /// 要执行的表达式
169 /// 运算结果
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 /// 
178 /// 静态方法的执行字符串名称
179 /// 
180 private const string StaticMethodName = "__foo";
181 /// 
182 /// 用于动态引用生成的类,执行其内部包含的可执行字符串
183 /// 
184 object _compiled = null;
185 #endregion
186 }
187 
188 
189 /// 
190 /// 可执行字符串项(即一条可执行字符串)
191 /// 
192 public class EvaluatorItem
193 {
194 /// 
195 /// 返回值类型
196 /// 
197 public Type ReturnType;
198 /// 
199 /// 执行表达式
200 /// 
201 public string Expression;
202 /// 
203 /// 执行字符串名称
204 /// 
205 public string Name;
206 /// 
207 /// 可执行字符串项构造函数
208 /// 
209 /// 返回值类型
210 /// 执行表达式
211 /// 执行字符串名称
212 public EvaluatorItem(Type returnType, string expression, string name)
213 {
214 ReturnType = returnType;
215 Expression = expression;
216 Name = name;
217 }
218 }

 

转载于:https://www.cnblogs.com/creater/p/6322029.html

你可能感兴趣的:(用来将字符串转为可执行文本并执行)