您的位置:首页 > 技术教程 > c#

一个极其简单的在线C#IDE例子
【字体: 整理日期:2008-5-15 8:40:03 打印本文】 【收藏此文

  五一时去朋友那, 他问了个小问题, 只要写几十行代码就可以很好的说明问题.可偏偏机子没装vs, 只好做罢.回来后想想, 要是有个在线的c#ide就好了.于是上网查了下相关的资料, 整出来个简单的在线c#ide.

  做这个,主要要解决两个问题, 一是如果将网页上文本框的代码编译并执行;二是如果将程序运行结果在网页上输出.

  第一个问题不难, .net已经有现成的c#编译类csharpcodeprovider(或是其它语言的),再使用compilerparameters类做为编译参数,就可以很容易的实现.

  第二个问题, 举最简单情况, 就是将console.write方法输出的内容在网页上显示出来.这其实也很好办,只要在编译之前, 在输出语句做一个替换, 将输出的内容存到另一个地方.等运行结束后, 再从那个地方取出来就是了.

  代码实现如下: 以下是引用片段:
using system;
  using system.collections.generic;
  using system.linq;
  using system.text;
  
  namespace vsonline.framework
  {
   /**////
   /// 自定义的输出类
   ///
   public class consoler
   {
   //存储所有输出
   public static dictionary outputs { get; set; }
  
   static consoler()
   {
   outputs = new dictionary();
   }
  
   输出操作#region 输出操作
  
   //当前输出
   public list output { get; private set; }
  
   public consoler()
   {
   output = new list();
   }
  
   public void write(object str)
   {
   output.add(str.tostring());
   }
  
   public void writeline(object str)
   {
   output.add(str.tostring() + "\n");
   }
  
   #endregion
   }
  }
  using system;
  using system.reflection;
  using microsoft.csharp;
  using system.codedom.compiler;
  using system.collections.generic;
  using system.linq;
  using system.web;
  
  namespace vsonline.framework
  {
   /**////
   /// 代码执行类
   ///
   public class coderun
   {
   /**////
   /// framework版本,可选择v2.0, v3.0, v3.5
   ///
   private string compilerversion { get; set; }
  
   /**////
   /// 构造函数
   ///
   /// framework版本,可选择v2.0, v3.0, v3.5
   public coderun(string compilerversion)
   {
   compilerversion = compilerversion;
   }
  
   /**////
   /// 构造函数,默认为3.5版本
   ///
   public coderun()
   {
   compilerversion = "v3.5";
   }
  
   /**////
   /// 动态编译并执行代码
   ///
   /// 代码
   /// 返回输出内容
   public list run(string code, string id, params string[] assemblies)
   {
   consoler.outputs.add(id, new consoler());
   compilerparameters compilerparams = new compilerparameters();
   //编译器选项设置
   compilerparams.compileroptions = "/target:library /optimize";
   //compilerparams.compileroptions += @" /lib:""c:\program files\reference assemblies\microsoft\framework\v3.5\""";
   //编译时在内存输出
   compilerparams.generateinmemory = true;
   //生成调试信息
   compilerparams.includedebuginformation = false;
   //添加相关的引用
   foreach (string assembly in assemblies)
   {
   compilerparams.referencedassemblies.add(assembly);
   }
   compilerparams.referencedassemblies.add("mscorlib.dll");
   compilerparams.referencedassemblies.add("system.dll");
   if (this.compilerversion == "v3.5")
   {
   compilerparams.referencedassemblies.add("system.core.dll");
   }
  
   string path = "";
   try
   {
   path = httpcontext.current.server.mappath("/bin/");
   }
   catch { }
  
   compilerparams.referencedassemblies.add(path + "vsonline.framework.dll");
   csharpcodeprovider compiler = new csharpcodeprovider(new dictionary() { { "compilerversion", compilerversion } });
   //编译
   code = code.replace("console.writeline", string.format("vsonline.framework.consoler.outputs[\"{0}\"].writeline", id));
   code = code.replace("console.write", string.format("vsonline.framework.consoler.outputs[\"{0}\"].write", id));
   compilerresults results = compiler.compileassemblyfromsource(compilerparams, code);
   //错误
   if (results.errors.haserrors)
   {
   foreach (compilererror error in results.errors)
   {
   consoler.outputs[id].output.add(error.errortext + "\n");
   }
  
   return returnoutput(id);
   }
   //创建程序集
   assembly asm = results.compiledassembly;
   //获取编译后的类型
   object mainclass = asm.createinstance("program");
   type mainclasstype = mainclass.gettype();
   //输出结果
   mainclasstype.getmethod("main").invoke(mainclass, null);
  
   return returnoutput(id);
   }
  
   private list returnoutput(string id)
   {
   string[] output = new string[consoler.outputs[id].output.count];
   consoler.outputs[id].output.copyto(output, 0);
   consoler.outputs.remove(id);
  
   return output.tolist();
   }
   }
  }
  
  测试:

   以下是引用片段:
using vsonline.framework;
  using microsoft.visualstudio.testtools.unittesting;
  using system.collections.generic;
  using system;
  using fastdev.core;
  using system.linq;
  
  namespace test
  {
   [testclass()]
   public class coderuntest
   {
   [testmethod()]
   public void runtest()
   {
   coderun target = new coderun();
  
   string code = @"
  using system;
  
  public class program
  {
   public static void main()
   {
   for(int index = 1;index <= 3;index++)
   {
   console.write(index);
   }
   }
  }
   ";
   list expected = new list() { "1", "2", "3" };
   list actual;
   actual = target.run(code, "1");
   assert.areequal(true, expected.serializeequal(actual));
  
   actual = target.run(code, "2");
   assert.areequal(true, expected.serializeequal(actual));
   }
  
   [testmethod()]
   public void run35test()
   {
   coderun target = new coderun();
  
   string code = @"
  using system;
  using system.collections;
  using system.collections.generic;
  using system.linq;
  
  public class program
  {
   public static string name { get; set; }
  
   public static void main()
   {
   name = ""3"";
   console.write(name);
   }
  }
   ";
   list actual;
   actual = target.run(code, "1", "system.core.dll");
   assert.areequal("3", actual[0]);
   }
   }
  }


查询
关键词:
相关文章
标签Tags