MathExpress.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. using Microsoft.CSharp;
  2. using System;
  3. using System.CodeDom.Compiler;
  4. using System.Reflection;
  5. using System.Text;
  6. namespace MathConsoleApp
  7. {
  8. /// <summary>
  9. /// 本类用来将字符串转为可执行文本并执行
  10. /// </summary>
  11. public class MyEvaluator
  12. {
  13. #region 构造函数
  14. /// <summary>
  15. /// 可执行串的构造函数
  16. /// </summary>
  17. /// <param name="items">
  18. /// 可执行字符串数组
  19. /// </param>
  20. public MyEvaluator(EvaluatorItem[] items)
  21. {
  22. ConstructEvaluator(items); //调用解析字符串构造函数进行解析
  23. }
  24. /// <summary>
  25. /// 可执行串的构造函数
  26. /// </summary>
  27. /// <param name="returnType">返回值类型</param>
  28. /// <param name="expression">执行表达式</param>
  29. /// <param name="name">执行字符串名称</param>
  30. public MyEvaluator(Type returnType, string expression, string name)
  31. {
  32. //创建可执行字符串数组
  33. EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) };
  34. ConstructEvaluator(items); //调用解析字符串构造函数进行解析
  35. }
  36. /// <summary>
  37. /// 可执行串的构造函数
  38. /// </summary>
  39. /// <param name="item">可执行字符串项</param>
  40. public MyEvaluator(EvaluatorItem item)
  41. {
  42. EvaluatorItem[] items = { item };//将可执行字符串项转为可执行字符串项数组
  43. ConstructEvaluator(items); //调用解析字符串构造函数进行解析
  44. }
  45. /// <summary>
  46. /// 解析字符串构造函数
  47. /// </summary>
  48. /// <param name="items">待解析字符串数组</param>
  49. private void ConstructEvaluator(EvaluatorItem[] items)
  50. {
  51. //创建C#编译器实例
  52. CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");
  53. //CodeDomProvider provider = new CSharpCodeProvider();
  54. //过时了
  55. //ICodeCompiler comp = provider.CreateCompiler();
  56. //编译器的传入参数
  57. CompilerParameters cp = new CompilerParameters();
  58. cp.ReferencedAssemblies.Add("System.dll"); //添加程序集 system.dll 的引用
  59. cp.ReferencedAssemblies.Add("System.Data.dll"); //添加程序集 system.data.dll 的引用
  60. cp.ReferencedAssemblies.Add("System.Xml.dll"); //添加程序集 system.xml.dll 的引用
  61. cp.GenerateExecutable = false; //不生成可执行文件
  62. cp.GenerateInMemory = true; //在内存中运行
  63. StringBuilder code = new StringBuilder(); //创建代码串
  64. /*
  65. * 添加常见且必须的引用字符串
  66. */
  67. code.Append("using System; \n");
  68. code.Append("using System.Data; \n");
  69. code.Append("using System.Data.SqlClient; \n");
  70. code.Append("using System.Data.OleDb; \n");
  71. code.Append("using System.Xml; \n");
  72. code.Append("namespace SSEC.Math { \n"); //生成代码的命名空间为EvalGuy,和本代码一样
  73. code.Append(" public class _Evaluator { \n"); //产生 _Evaluator 类,所有可执行代码均在此类中运行
  74. foreach (EvaluatorItem item in items) //遍历每一个可执行字符串项
  75. {
  76. code.AppendFormat(" public {0} {1}() ", //添加定义公共函数代码
  77. item.ReturnType.Name, //函数返回值为可执行字符串项中定义的返回值类型
  78. item.Name); //函数名称为可执行字符串项中定义的执行字符串名称
  79. code.Append("{ "); //添加函数开始括号
  80. code.AppendFormat("return ({0});", item.Expression);//添加函数体,返回可执行字符串项中定义的表达式的值
  81. code.Append("} \n"); //添加函数结束括号
  82. }
  83. code.Append("} }"); //添加类结束和命名空间结束括号
  84. //得到编译器实例的返回结果
  85. CompilerResults cr = provider.CompileAssemblyFromSource(cp, code.ToString());//comp
  86. if (cr.Errors.HasErrors) //如果有错误
  87. {
  88. StringBuilder error = new StringBuilder(); //创建错误信息字符串
  89. error.Append("编译有错误的表达式: "); //添加错误文本
  90. foreach (CompilerError err in cr.Errors) //遍历每一个出现的编译错误
  91. {
  92. error.AppendFormat("{0}\n", err.ErrorText); //添加进错误文本,每个错误后换行
  93. }
  94. throw new Exception("编译错误: " + error.ToString());//抛出异常
  95. }
  96. Assembly a = cr.CompiledAssembly; //获取编译器实例的程序集
  97. _Compiled = a.CreateInstance("SSEC.Math._Evaluator"); //通过程序集查找并声明 SSEC.Math._Evaluator 的实例
  98. }
  99. #endregion 构造函数
  100. #region 公有成员
  101. /// <summary>
  102. /// 执行字符串并返回整型值
  103. /// </summary>
  104. /// <param name="name">执行字符串名称</param>
  105. /// <returns>执行结果</returns>
  106. public int EvaluateInt(string name)
  107. {
  108. return (int)Evaluate(name);
  109. }
  110. /// <summary>
  111. /// 执行字符串并返回双精度值
  112. /// </summary>
  113. /// <param name="name">执行字符串名称</param>
  114. /// <returns>执行结果</returns>
  115. public double EvaluateDouble(string name)
  116. {
  117. return (double)Evaluate(name);
  118. }
  119. /// <summary>
  120. /// 执行字符串并返回长整型数值
  121. /// </summary>
  122. /// <param name="name">执行字符串名称</param>
  123. /// <returns>执行结果</returns>
  124. public long EvaluateLong(string name)
  125. {
  126. return (long)Evaluate(name);
  127. }
  128. /// <summary>
  129. /// 执行字符串并返回十进制数值
  130. /// </summary>
  131. /// <param name="name">执行字符串名称</param>
  132. /// <returns>执行结果</returns>
  133. public decimal EvaluateDecimal(string name)
  134. {
  135. return (decimal)Evaluate(name);
  136. }
  137. /// <summary>
  138. /// 执行字符串并返回字符串型值
  139. /// </summary>
  140. /// <param name="name">执行字符串名称</param>
  141. /// <returns>执行结果</returns>
  142. public string EvaluateString(string name)
  143. {
  144. return (string)Evaluate(name);
  145. }
  146. /// <summary>
  147. /// 执行字符串并返回布尔型值
  148. /// </summary>
  149. /// <param name="name">执行字符串名称</param>
  150. /// <returns>执行结果</returns>
  151. public bool EvaluateBool(string name)
  152. {
  153. return (bool)Evaluate(name);
  154. }
  155. /// <summary>
  156. /// 执行字符串并返 object 型值
  157. /// </summary>
  158. /// <param name="name">执行字符串名称</param>
  159. /// <returns>执行结果</returns>
  160. public object Evaluate(string name)
  161. {
  162. MethodInfo mi = _Compiled.GetType().GetMethod(name);//获取 _Compiled 所属类型中名称为 name 的方法的引用
  163. return mi.Invoke(_Compiled, null); //执行 mi 所引用的方法
  164. }
  165. #endregion 公有成员
  166. #region 静态成员
  167. /// <summary>
  168. /// 执行表达式并返回整型值
  169. /// </summary>
  170. /// <param name="code">要执行的表达式</param>
  171. /// <returns>运算结果</returns>
  172. static public int EvaluateToInteger(string code)
  173. {
  174. MyEvaluator eval = new MyEvaluator(typeof(int), code, staticMethodName);//生成 Evaluator 类的对像
  175. return (int)eval.Evaluate(staticMethodName); //执行并返回整型数据
  176. }
  177. /// <summary>
  178. /// 执行表达式并返回双精度值
  179. /// </summary>
  180. /// <param name="name">执行字符串名称</param>
  181. /// <returns>执行结果</returns>
  182. static public double EvaluateToDouble(string code)
  183. {
  184. MyEvaluator eval = new MyEvaluator(typeof(double), code, staticMethodName);//生成 Evaluator 类的对像
  185. return (double)eval.Evaluate(staticMethodName);
  186. }
  187. /// <summary>
  188. /// 执行表达式并返回长整型数值
  189. /// </summary>
  190. /// <param name="name">执行字符串名称</param>
  191. /// <returns>执行结果</returns>
  192. static public long EvaluateToLong(string code)
  193. {
  194. MyEvaluator eval = new MyEvaluator(typeof(long), code, staticMethodName);//生成 Evaluator 类的对像
  195. return (long)eval.Evaluate(staticMethodName);
  196. }
  197. /// <summary>
  198. /// 执行表达式并返回十进制数值
  199. /// </summary>
  200. /// <param name="name">执行字符串名称</param>
  201. /// <returns>执行结果</returns>
  202. static public decimal EvaluateToDecimal(string code)
  203. {
  204. MyEvaluator eval = new MyEvaluator(typeof(decimal), code, staticMethodName);//生成 Evaluator 类的对像
  205. return (decimal)eval.Evaluate(staticMethodName);
  206. }
  207. /// <summary>
  208. /// 执行表达式并返回字符串型值
  209. /// </summary>
  210. /// <param name="code">要执行的表达式</param>
  211. /// <returns>运算结果</returns>
  212. static public string EvaluateToString(string code)
  213. {
  214. MyEvaluator eval = new MyEvaluator(typeof(string), code, staticMethodName);//生成 Evaluator 类的对像
  215. return (string)eval.Evaluate(staticMethodName); //执行并返回字符串型数据
  216. }
  217. /// <summary>
  218. /// 执行表达式并返回布尔型值
  219. /// </summary>
  220. /// <param name="code">要执行的表达式</param>
  221. /// <returns>运算结果</returns>
  222. static public bool EvaluateToBool(string code)
  223. {
  224. MyEvaluator eval = new MyEvaluator(typeof(bool), code, staticMethodName);//生成 Evaluator 类的对像
  225. return (bool)eval.Evaluate(staticMethodName); //执行并返回布尔型数据
  226. }
  227. /// <summary>
  228. /// 执行表达式并返回 object 型值
  229. /// </summary>
  230. /// <param name="code">要执行的表达式</param>
  231. /// <returns>运算结果</returns>
  232. static public object EvaluateToObject(string code)
  233. {
  234. MyEvaluator eval = new MyEvaluator(typeof(object), code, staticMethodName);//生成 Evaluator 类的对像
  235. return eval.Evaluate(staticMethodName); //执行并返回 object 型数据
  236. }
  237. #endregion 静态成员
  238. #region 私有成员
  239. /// <summary>
  240. /// 静态方法的执行字符串名称
  241. /// </summary>
  242. private const string staticMethodName = "__foo";
  243. /// <summary>
  244. /// 用于动态引用生成的类,执行其内部包含的可执行字符串
  245. /// </summary>
  246. private object _Compiled = null;
  247. #endregion 私有成员
  248. }
  249. /// <summary>
  250. /// 可执行字符串项(即一条可执行字符串)
  251. /// </summary>
  252. public class EvaluatorItem
  253. {
  254. /// <summary>
  255. /// 返回值类型
  256. /// </summary>
  257. public Type ReturnType;
  258. /// <summary>
  259. /// 执行表达式
  260. /// </summary>
  261. public string Expression;
  262. /// <summary>
  263. /// 执行字符串名称
  264. /// </summary>
  265. public string Name;
  266. /// <summary>
  267. /// 可执行字符串项构造函数
  268. /// </summary>
  269. /// <param name="returnType">返回值类型</param>
  270. /// <param name="expression">执行表达式</param>
  271. /// <param name="name">执行字符串名称</param>
  272. public EvaluatorItem(Type returnType, string expression, string name)
  273. {
  274. ReturnType = returnType;
  275. Expression = expression;
  276. Name = name;
  277. }
  278. }
  279. }