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 }