前不久看了一个C#菜鸟级工具 功能是在form写代码,重新编译在Console里执行
当时觉得这东西很新颖,就下载下来看看,没想到坑爹的竟然是F#语言写的,会函数式语言有几个菜鸟啊啊啊啊- -
本着好奇精神,也为了在每月开会能有什么东西能讲,于是自己在网上找了点资料自己写了一个,运行图如下
OK,程序本身很简单,在Console基础上new一个form,然后form的button事件则是调用Console方法然后重编译这段代码执行
以下是构造函数里拼接代码的部分。
/// <summary> /// 解析字符串构造函数 /// </summary> /// <param name="items">待解析字符串数组</param> private void ConstructEvaluator(EvaluatorItem[] items) { //创建C#编译器实例 ICodeCompiler comp = (new CSharpCodeProvider().CreateCompiler()); //编译器的传入参数 CompilerParameters cp = new CompilerParameters(); cp.ReferencedAssemblies.Add("system.dll"); //添加程序集 system.dll 的引用 cp.ReferencedAssemblies.Add("system.data.dll"); //添加程序集 system.data.dll 的引用 cp.ReferencedAssemblies.Add("system.xml.dll"); //添加程序集 system.xml.dll 的引用 cp.GenerateExecutable = false; //不生成可执行文件 cp.GenerateInMemory = true; //在内存中运行 StringBuilder code = new StringBuilder(); //创建代码串 /* * 添加常见且必须的引用字符串 */ code.Append("using System; \n"); code.Append("using System.Data; \n"); //code.Append("using System.Data.SqlClient; \n"); //code.Append("using System.Data.OleDb; \n"); //code.Append("using System.Xml; \n"); code.Append("namespace EvalGuy { \n"); //生成代码的命名空间为EvalGuy,和本代码一样 code.Append(" public class _Evaluator { \n"); //产生 _Evaluator 类,所有可执行代码均在此类中运行 foreach (EvaluatorItem item in items) //遍历每一个可执行字符串项 { code.AppendFormat(" public {0} {1}() ", //添加定义公共函数代码 item.ReturnType.Name, //函数返回值为可执行字符串项中定义的返回值类型 item.Name); //函数名称为可执行字符串项中定义的执行字符串名称 code.Append("{\n"); //添加函数开始括号 string[] strs = item.Expression.Split(';'); code.Append("object obj=\"\";\n"); code.Append("try{\n"); foreach (string s in strs) { code.Append(s + ";\n"); } code.Append("}\n catch{}\n"); code.Append("return obj;"); code.Append("}\n"); //添加函数结束括号 } code.Append("} }"); //添加类结束和命名空间结束括号 //得到编译器实例的返回结果 CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString()); try { ; } catch { } if (cr.Errors.HasErrors) //如果有错误 { StringBuilder error = new StringBuilder(); //创建错误信息字符串 error.Append("编译有错误的表达式: "); //添加错误文本 foreach (CompilerError err in cr.Errors) //遍历每一个出现的编译错误 { error.AppendFormat("{0}\n", err.ErrorText); //添加进错误文本,每个错误后换行 } MessageBox.Show("编译错误: " + error.ToString()); return; } Assembly a = cr.CompiledAssembly; //获取编译器实例的程序集 _Compiled = a.CreateInstance("EvalGuy._Evaluator"); //通过程序集查找并声明 EvalGuy._Evaluator 的实例 }
至于这个工具作用,那篇文章写的很清楚了:基本没用。。。至少我这2个星期在工作中没用到它。
菜鸟工具,Demo下载地址